Заполнение связанных списков на MS AJAX и jQuery.
Технология MS AJAX появилась в качестве приблуды еще в Visual Studio 2005 (не сразу, а после SP1) - изначально она называлась ATLAS. Я изучал эту технологию еще по первым книгам по АТЛАСУ . К моменту появления Visual Studio 2008 этой технологий пользовались уже все ASP.NET программисты. У меня на сайте подробно описаны несколько форм на MS AJAX, например в топике - Мой первый фото-слайдер на Flex 4.
Программисты других платформ часто тупят и думают что MS AJAX чем-то напоминает обычный AJAX из JavaScript. Собственно движок асинхронных AJAX-запросов в технологии MS AJAX действительно присутствует, однако это внутренний (как-бы невидимый) скриптик, подтягиваемый из ScriptResource - а вообще вся суть этой технологии в том, чтобы сконфигурировать асинхронный AJAX-запрос ИСКЛЮЧИТЕЛЬНО КЛИКАМИ МЫШКОЙ в Visual Studio. Навык применения MS AJAX состоит из умения точно кликнуть мышков с первого раза в нужном месте экрана, выбрать там правильный параметр, в понимании смысла этих параметров, в умении пользоваться конфигураторатором студии для того или иного варианта использования MS AJAX.
Ниже я покажу десять волшебных кликов мышкой, которые позволяют сконфигурировать AJAX-запросы простейшим образом (и парсинг ответов) БЕЗ ПРОГРАММИРОВАНИЯ - только тыканием мышки в нужные места на экране. А еще ниже я покажу как в точности то же самое делается путем программирования (на jQuery).
Итак, есть два DropDownList (select/option в HTML). Один страна, другой город. По выбору страны - надо заполнить второй список городами. Для этого тыкаем мышкой в следующие места на экране:
- ШАГ 1. Cначала перетаскиваем на master-page контрол ScriptManager.
- ШАГ 2. Перетасиваем на форму контрол UpdatePanel и вставляем внутрь него нужный контрол - который будет обновляться без постбека.
- ШАГ 3. Конфигурируем триггер - выставляем контрол и событие контрола, по которому будет обновляться содержимое UpdatePanel.
- ШАГ 4. Ставим параметры UpdatePanel. Обычно conditional (чтобы можно было вручную командой update обновлять содержимое UpdatePanel).
- ШАГ 5. Контролу, чье событие отслеживаем - ставим AutoPostback=True
- ШАГ 6. Создаем в два тычка мышкой событие, которое будет обрабатываться асинхронно. Первый тык - выбор контрола, второй тык - выбор события.
- ШАГ 7. Конфигурирование завершено. Проверяем все.
- Теперь вводим собственно код асинхронно-исполняемого метода. У меня уже сконфигурирован LINQ To SQL - поэтому для показа данных в связанном списке я ввожу всего восемь коротеньких строчек бейсика (фактически даже не ввожу, а просто выбираю то, что мне подсказывает студия):
1: ''' <summary>
2: ''' Это выполняется асинхронно, минуя полный постбек
3: ''' </summary>
4: Protected Sub cbFromCountry_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbFromCountry.SelectedIndexChanged
5: Dim DB1 As New FlySeasonDataContext
6: Dim AllRecords As System.Collections.Generic.List(Of GetCityResult) = DB1.GetCity(CType(sender, DropDownList).Text).ToList()
7: cbFromCity.DataTextField = "City"
8: cbFromCity.DataValueField = "City"
9: cbFromCity.DataSource = AllRecords
10: cbFromCity.DataBind()
11: UpdatePanel1.Update()
12: End Sub
Фактически длинное выражение в строке 6 тоже можно было бы не вводить - это просто привычка из седьмого бейсика. Дело в том, что в шестом бейсике анонимные типы были. Но потом микрософтовцы зачем-то для некоторыго узкого подмножества Windows-задач придумали тупой и ограниченный СиШарп. Настолько тупой, что в нем даже не было анонимных типов. А IL-код то ведь одинаковый у бейсика и тупого Шарпа. Из-за этого в седьмом бейсике вышло такое торможение - что из него выбросили анонимные типы. И только когда тупой Шарп чуть-чуть подтянули - нормальные привычные всем по шестому бейсику анонимные типы наконец-то снова появились в восьмом бейсике. Впрочем недоделанный Шарп так и остался недоделанным глюком. Им по прежнему невозможно создать натуральные COM-обьекты (без NET) - что все обычно делают на шестом бейсике. На тупом Шарпе по-прежнему нельзя делать в полной мере автоматизацию Офиса. Нельзя делать скрипты SSIS-пакетов для SQL-сервера. Нельзя писать WSH-скрипты для автоматизации Windows - и так далее. В общем от этого глюка грех один получился. Шарперам только остается убить себя ап стену, когда нужно выполнять какие-то самые обычные задачи в Windows - написать скриптик для инсталятора (c остуствующей на кампутере NET), написать COM-обьект, написать Windows Script Host - скрипт например для создания узлов в IIS или выдернуть им что-то по LDAP из Active Directory и так далее. Фактически больше всех от Шарпа пострадали не сами Шарперы (они обычно имеют настолько узкий кругозор, что даже не понимают своей ограниченности) - пострадали бейсик-программисты, которые в течении пяти лет были лишены возможности пользоваться любимыми анонимными типами, и прочими фишками из бейсика 1998 года, которое только-только появились наконец-то в убогом новоиспеченном Шарпе.
- Все, после ввода этих восьми строчек - можно делать комплексную проверку заполнения связнного списка.
Как видите, все чудесно работает. Асинхронный запрос AJAX был сконфигурирован и отлажен в течении минуты - десят строк кода плюс двадцать кликов мышкой.
Теперь сделаем все то же самое с помощью jQuery. В общем, времени это займет наверное побольше - плюс потребуются навыки программирования. Все начинается с хандлера, который должен выдать корректный JSON - как это делается я описывал уже не раз в своих рецептах, см например Как сделать простейший Web-handler - формирующий XML или JSON.
Затем я написал вот такой копеечный jQuery-скриптик:
1: $(document).ready(function () {
2:
3: $('#FromCountry').bind('change', fill_from_city);
4:
5: function fill_from_city() {
6: $.ajax({
7: 'url': 'GetCity.ashx',
8: 'data': { 'country': $('#FromCountry').val() },
9: 'dataType': 'json',
10: 'type': 'GET',
11: 'success': from_city_result
12: });
13: };
14:
15: function from_city_result(json_array) {
16: if (json_array.length) {
17: $('#FromCity option').remove();
18: $.each(json_array, function (index, term) {
19: $('#FromCity').append(
20: $('<option></option>').val(term.Name).html(term.Name)
21: );
22: });
23: }
24: };
25: });
Для того, чтобы вытащить значение подчиненного списка в ASP.NET - я добавил на страничке ASP.NET два скрытых поля:
1: <asp:TextBox ID="txFromCity" runat="server" style="visibility:hidden;width:0px;height:0px;" ></asp:TextBox>
2: <asp:TextBox ID="txToCity" runat="server" style="visibility:hidden;width:0px;height:0px;"></asp:TextBox>
И положил в них значение 'город' из подчиненного списка страна-город.
27: $(document).ready(function () {
28:
29: $('#ToCity').bind('change', tocity_change);
30: $('#FromCity').bind('change', fromcity_change);
31:
32: function tocity_change() {
33: $('#txToCity').val($('#ToCity').val());
34: };
35:
36: function fromcity_change() {
37: $('#txFromCity').val($('#FromCity').val());
38: };
39:
40: });
Осталось только проверить как все работает:
Описанная задачка заполнения связанных списков проста предельно. В дикой природе такие простые задачки встречаются редко. Лично мне опыт позволяет решать эту задачку за примерно одинаковое время и и на jQuery и на MS AJAX (и на Flex) - но на основании моей заметки вы можете оценить свои силы и выбрать подходящий для себя путь в более сложных случаях.
|