Использование шаблона JavaScript с ASP.NET

#c# #javascript #asp.net #ajax #templates

#c# #javascript #asp.net #ajax #шаблоны

Вопрос:

Я сталкивался с этой проблемой несколько раз за свою карьеру, и так и не смог найти для нее элегантного решения. Представьте, что у вас есть простая страница, на которой есть повторитель. Вы заполняете этот повторитель на стороне сервера через привязку данных. Это здорово, работает быстро и делает то, что должно. Но теперь вы хотите добавить paginator к этому повторителю или иным образом изменить вывод. Выполнение этого через Ajax является предпочтительным способом обеспечения расширенного взаимодействия с клиентом.

Итак, вы создаете веб-сервис, который предоставляет вам данные в формате JSON, но теперь вы застряли… Либо вам нужно написать сложный код на стороне клиента, чтобы найти каждое поле, которое вам нужно изменить в каждом элементе repeater, либо вам нужно удалить весь вывод repeater на стороне сервера и создать новый HTML с нуля, или, метод, который я использую в последнее время, возьмите первый повторяющийся элемент, удалите все остальное и клонируйте первый элемент столько раз, сколько вам нужно, и модифицируйте его поля.

Все описанные методы не являются оптимальными, потому что, несмотря ни на что, они требуют довольно много повторяющейся логики на стороне сервера (т.Е. шаблона в repeater) и на стороне клиента (javascript для отображения данных JSON). Должен быть лучший, более простой способ сделать это. Первое, что приходит на ум, это вместо возврата JSON с веб-сервера вернуть HTML предварительно заполненного повторителя. Но для чего-то подобного я мог бы также использовать ASP.NET Панель обновления AJAX. Результат не будет меньше с автономным веб-сервисом.

Следующее, о чем я подумал, это шаблоны JavaScript. Что, если бы был какой-то способ взять необработанный шаблон repeater на стороне сервера и преобразовать его в шаблон JavaScript, который мог бы быть либо встроен на страницу при загрузке, либо обслуживаться как часть ответа веб-службы. Однако я не смог найти никаких существующих решений для чего-то подобного. И я не могу придумать простой способ сделать это сам. Есть идеи?

P.S. О рендеринге шаблона JavaScript на стороне клиента при загрузке страницы и использовании JavaScript для его заполнения без отображения исходного представления на сервере (без повторителя и привязки к данным) не может быть и речи. Я слишком забочусь о производительности.

Комментарии:

1. Насколько ухудшится ваша производительность, если вы передадите шаблоны клиенту? Это буквально будет лучшим решением.

2. Вовсе нет. Если вы привязываете данные на сервере для начальной загрузки страницы, вы возвращаете чистый HTML. Если вы отправляете обратно шаблон javascript и JSON (либо как часть страницы, либо, не дай бог, как AJAX-запрос), вам нужно не только отправлять чистый HTML, вам также придется обрабатывать его с помощью JavaScript после завершения загрузки страницы. Начальная загрузка страницы всегда должна быть полностью отрисована на сервере, поскольку это контролируемая среда.

3. Многие хорошо посещаемые сайты, такие как gmail, не согласились бы с этим.

4. Я почти уверен, что они не стали бы возражать. Здесь не так уж много поводов для разногласий. Если ваш сервер не справляется с нагрузкой, это просто, просто обновите свой сервер, получите больше памяти и лучший процессор, добавьте больше узлов в ферму. Вы контролируете ситуацию. Однако, если ваши клиенты используют IE6 на компьютерах Pentium I, при этом обработка видео выполняется в фоновом режиме, вы вообще ничего не можете с этим поделать… Так что я не думаю, что Google не согласится, я думаю, что они просто пытаются свести затраты на разработку к минимуму.

Ответ №1:

Во-первых, я не верю, что использование шаблона клиента с данными JSON даже при первой загрузке отрицательно повлияет на производительность, если только мы не говорим об устройствах с разными форм-факторами, таких как телефоны и т.д.

Однако, если вы должны использовать шаблоны / рендеринг на стороне сервера, то почему бы не заставить сервер возвращать html для повторителя. Это можно сделать, поместив логику повторителя в другой пользовательский элемент управления / страницу и обрабатывая только эту страницу по запросу ajax. И это совсем не эквивалентно использованию UpdatePanel (как указано вами) — UpdatePanel публикует данные всей страницы (включая состояние просмотра), имеющие больший размер запроса. Размер ответа также велик, потому что он должен содержать состояние просмотра. На стороне сервера также использование UpdatePanel приводит к загрузке полного дерева управления с данными о состоянии и последующей обработке событий. Отправка только необходимого html-кода является гораздо лучшим подходом и идеально соответствует вашим потребностям — единственная проблема в том, что html будет больше по размеру по сравнению с JSON.

Наконец, есть несколько интересных проектов, таких как Script# — Скрипт # преобразует код C # в java-script. Вы можете создать нечто подобное (используя сам script #), чтобы преобразовать код шаблона на стороне сервера в эквивалентный JS-код. Более жизнеспособным подходом в аналогичных направлениях могло бы быть использование шаблонов T4 для преобразования не зависящего от технологии шаблона как в код на стороне сервера (разметка код или чистый код), так и в эквивалентный JS-код.

Комментарии:

1. Если мы говорим о примере, который я привел — верно, производительность не сильно пострадает. Но на реальном примере большой страницы с несколькими областями, связанными с данными, или одной очень большой области с несколькими переменными, которая связана с данными, это, вероятно, будет заметно. Согласен с UpdatePanels, я просто так долго отключал view-state на своих страницах, что забыл об этом 🙂 Хорошая идея для Script #. Я посмотрю, и шаблоны T4, в теории звучит неплохо, но на практике, я думаю, будет больше проблем, чем того стоит.

2. @Ilya, я указал Script # для концептуальной перспективы. ИМО, потребовалось бы больше усилий, чтобы использовать это для этой конкретной потребности или создать что-то подобное. Я все еще считаю, что использование какого-либо пользовательского движка шаблонов, такого как T4, выполнимо и обеспечивает большую гибкость.

Ответ №2:

Поразмыслив обо всех плюсах и минусах различных подходов, я остановился на следующем методе. Я создал пользовательский ASP.NET элемент управления databound, который может отображать HTML, однако, когда страница запрашивается с параметрами строки запроса, вместо того, чтобы просто выполнять стандартный рендеринг, он будет использовать Response.Clear() и Response.End(), а между этими двумя командами выводится версия данных в формате JSON на основе параметров строки запроса. Также при первом рендеринге страницы он также выведет шаблон JavaScript, используя отражения для чтения имен переменных из области шаблона элемента управления.

Этот метод отлично работает, все, что мне нужно сделать, это поместить свой элемент управления на страницу, привязать его к данным, и он работает как настоящая сетка AJAX, которая поддерживает разбивку на страницы, сортировку и фильтрацию. Однако у него есть ограничение. В шаблоне элемента управления вы можете указывать только переменные, а не выражения. В противном случае reflections не смогут преобразовать его в переменную JavaScript. Но я могу с этим смириться.

Другие возможности, которые я рассмотрел, — это отдельный веб-сервис, который принимает тип страницы в качестве параметра и использует отражение для получения объекта с привязкой к данным, а также для создания шаблона для сетки. Я также думал о написании моей собственной версии панели обновления, которая не использовала бы состояние просмотра и отправляла только часть страницы.