ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

Установка опций Ajax

Мы можем точно настроить поведение наших Ajax запросов, установив значения для свойств объекта AjaxOptions, который мы передаем вспомогательному методу Ajax.BeginForm. В следующих разделах мы объясняем, что каждая из этих опций делает и почему они могут быть полезны.

Обеспечение постепенного ухудшения

Когда мы создали форму с поддержкой Ajax в листинге 21-11, мы асинхронно передали имя метода действия, который должен быть вызван. В нашем примере это было действие GetPeopleData, которое генерирует частичное представление, содержащее фрагмент HTML.

Одна проблема с этим подходом заключается в том, что все это не очень хорошо работает, если пользователь отключил JavaScript (или использует браузер, который не поддерживает его). В таких случаях, когда пользователь отправляет форму, браузер отменяет отображение текущий HTML страницы и заменяет ее фрагментом, возвращенным целевым методом действия. Результат показан на рисунке 21-3.

Рисунок 21-3: Результат использования вспомогательного метода Ajax.BeginForm без браузерной поддержки JavaScript

Самым простым способом решения этой проблемы является использование свойства AjaxOptions.Url для определения целевого URL для асинхронного запроса вместо указания имени действия в качестве аргумента метода Ajax.BeginForm, как показано в листинге 21-12.

Листинг 21-12: Использование свойства AjaxOptions.Url для обеспечения постепенного ухудшения
@using HelperMethods.Models
@model string
@{
	ViewBag.Title = "GetPeople";
	AjaxOptions ajaxOpts = new AjaxOptions {
		UpdateTargetId = "tableBody",
		Url = Url.Action("GetPeopleData")
	};
}
<h2>Get People</h2>
<table>
	<thead>
		<tr>
			<th>First</th>
			<th>Last</th>
			<th>Role</th>
		</tr>
	</thead>
	<tbody id="tableBody">
		@Html.Action("GetPeopleData", new {selectedRole = Model })
	</tbody>
</table>
@using (Ajax.BeginForm(ajaxOpts)) {
<div>
	@Html.DropDownList("selectedRole", new SelectList(
		new [] {"All"}.Concat(Enum.GetNames(typeof(Role)))))
	<button type="submit">Submit</button>
</div>
}

Мы использовали вспомогательный метод Url.Action для создания URL, который будет вызывать действие GetPeopleData, и использовали версию метода Ajax.BeginForm, который принимает только параметр AjaxOptions. В результате этого создается элемент form, который отправляется обратно в исходный метод действия, если JavaScript не включен:

...
<form action="/People/GetPeople" data-ajax="true" data-ajax-mode="replace"
	data-ajax-update="#tableBody" data-ajax-url="/People/GetPeopleData" id="form0"
	method="post">
...

Если JavaScript включен, то библиотека ненавязчивого Ajax примет целевой URL из атрибута data-ajax-url, который относится к дочернему действию. Если JavaScript отключен, то браузер будет использовать обычную методику размещения формы, когда целевой URL принимается от атрибута action, указывающего обратно на метод действия, который будет генерировать полную HTML страницу.

Внимание

Вы можете удивиться, почему мы так заботимся о пользователях, которые отключили JavaScript. И кто же эти пользователи? На самом деле, такие пользователи делятся на две группы. Первая группа состоит из тех, кто очень серьезно воспринимает свою IT-безопасность и отключает все, что может быть использовано для атак: а этим JavaScript славится уже на протяжении многих лет. Вторая группа – это пользователи в крупных корпорациях, где применяется невероятная ограничительная политика во имя IT-безопасности (хотя, по нашему опыту, корпоративные ПК так плохо настроены, что безопасности тут просто не существует, а ограничения лишь раздражают пользователей). Вы можете игнорировать постепенное ухудшение, если чувствуете, что можете игнорировать экспертов по безопасности и людей, которые работают для крупных компаний. Но так как они могут быть технически подкованными и знающими пользователями, мы всегда уделяем время на то, чтобы не оставлять их в стороне.

Предоставление пользователям обратной связи при создании Ajax запроса

Один из недостатков использования Ajax заключается в том, что для пользователя не очевидно, что что-то происходит, потому что запрос к серверу производится в фоновом режиме. Мы можем сообщить пользователю, что запрос выполняется, при помощи свойств AjaxOptions.LoadingElementId и AjaxOptions.LoadingElementDuration. В листинге 21-13 показано, как мы применили эти свойства для файла представления GetPerson.cshtml.

Листинг 21-13: Создание обратной связи с пользователем при помощи свойства LoadingElementId
@using HelperMethods.Models
@model string
@{
	ViewBag.Title = "GetPeople";
	AjaxOptions ajaxOpts = new AjaxOptions {
		UpdateTargetId = "tableBody",
		Url = Url.Action("GetPeopleData"),
		LoadingElementId = "loading",
		LoadingElementDuration = 1000,
	};
}
<h2>Get People</h2>
<div id="loading" class="load" style="display: none">
	<p>Loading Data...</p>
</div>
<table>
	<thead>
		<tr>
			<th>First</th>
			<th>Last</th>
			<th>Role</th>
		</tr>
	</thead>
	<tbody id="tableBody">
		@Html.Action("GetPeopleData", new {selectedRole = Model })
	</tbody>
</table>
@using (Ajax.BeginForm(ajaxOpts)) {
<div>
	@Html.DropDownList("selectedRole", new SelectList(
new [] {"All"}.Concat(Enum.GetNames(typeof(Role)))))
	<button type="submit">Submit</button>
</div>
}

Свойство AjaxOptions.LoadingElementId определяет значение атрибута id скрытого HTML элемента, который будет показан пользователю, когда выполняется Ajax запрос. Чтобы показать эту возможность, мы добавили к представлению элемент div, который мы скрыли от пользователя, установив значение CSS свойства display на none. Мы дали этому элементу div id атрибут loading и использовали этот id в качестве значения для свойства LoadingElementId. Ненавязчивый Ajax будет отображать элемент для пользователя во время выполнения запроса, как показано на рисунке 21-4. Свойство LoadingElementDuration задает продолжительность анимации, который используется, чтобы показать элемент loading пользователю. Мы определили значение 1000, которое обозначает одну секунду.

Рисунок 21-4: Обратная связь с пользователем во время выполнения Ajax запроса

Подсказка для пользователя перед тем, как он сделал запрос

Свойство AjaxOptions.Confirm позволяет нам указать сообщение, которое будет использоваться как подсказка для пользователя перед каждым асинхронным запросом. Пользователь может выбрать дальнейшее выполнение или отмену запроса. В листинге 21-14 показано, как мы применили это свойство в файле GetPerson.cshtml.

Листинг 21-14: Подсказка для пользователя перед тем, как он сделал запрос
...
@{
	ViewBag.Title = "GetPeople";
	AjaxOptions ajaxOpts = new AjaxOptions {
		UpdateTargetId = "tableBody",
		Url = Url.Action("GetPeopleData"),
		LoadingElementId = "loading",
		LoadingElementDuration = 1000,
		Confirm = "Do you wish to request new data?"
};
}
...

С этим дополнением пользователю каждый раз при отправки формы показывается окно с сообщением, как представлено на рисунке 21-5. Это окно предлагается пользователю при каждом запросе. Это означает, что данную функцию следует использовать с осторожностью, чтобы не раздражать пользователя.

Рисунок 21-5: Окно с сообщением для пользователя перед отправкой запроса
или RSS канал: Что новенького на smarly.net