Как уменьшить дублирование просмотра между клиентом и сервером? - PullRequest
3 голосов
/ 08 декабря 2008

Я работаю над проектом AJAXy (Dojo и Rails, если подробности имеют значение). Есть несколько мест, где пользователь должен иметь возможность сортировать, группировать и фильтровать результаты. Также есть места, где пользователь заполняет короткую форму, и полученный элемент добавляется в список на той же странице.

Реализация без AJAXy работает нормально - серверная часть уровня представления уже знает, как визуализировать этот материал, поэтому она может просто сделать это снова в другом порядке или с дополнительным элементом. Это, однако, увеличивает нагрузку на сервер.

Итак, мы переключились на отправку JSON с сервера и много (ре) рендеринга на стороне клиента. Недостатком является то, что теперь у нас есть дублирующий код для рендеринга каждой страницы: один раз в Rails, который был создан для этого, и один раз в Dojo, который не был. Последнее в основном просто конкатенация строк.

Итак, первый вопрос: есть ли хорошая Javascript MVC-инфраструктура, которую мы могли бы использовать, чтобы сделать рендеринг на стороне клиента более удобным для сопровождения?

И второй вопрос: есть ли способ генерировать представления на стороне клиента в Javascript и представления на стороне сервера в ERB из одного и того же шаблона? Я думаю, что именно так поступили бы прагматичные программисты.

В качестве альтернативы, вопрос третий: я полностью пропускаю другой угол? Может быть, отправить JSON с сервера, но также включить фрагмент HTML в качестве атрибута, чтобы Javascript мог выполнять фильтрацию, сортировку и т. Д., А затем просто вставить данный фрагмент?

Ответы [ 7 ]

1 голос
/ 08 декабря 2008

Что ж, каждый раз, когда вы генерируете фрагменты HTML на клиенте и на сервере, вы можете получить дублированный код. Там нет хорошего пути обойти это вообще. Но вы можете сделать две вещи:

  1. Генерация всего на сервере. Используйте AHAH , когда вам нужно динамически генерировать фрагменты HTML. Обычно вы просите сервер сгенерировать фрагмент HTML, получить его асинхронно и подключить его на месте, используя innerHTML или любой другой подобный механизм.
  2. Генерируйте все на клиенте (AKA - парадигма толстого клиента). В этом случае даже для первоначального рендеринга вы передаете данные вместо предварительно отрендеренного HTML и обрабатываете данные на стороне клиента, используя JavaScript для создания HTML. В зависимости от ситуации вы можете использовать технику острова данных или запрашивать данные асинхронно. Вариант: включите его как , используя JSONP , чтобы браузер отправил вам запрос при загрузке страницы.

Оба подхода очень просты и имеют разные плюсы и минусы. Иногда возможно объединить оба метода в одном веб-приложении для разных частей данных.

Конечно, вы можете пойти на экзотические решения, такие как использование серверной среды на основе JavaScript. В этом случае вы можете поделиться кодом между сервером и клиентом.

0 голосов
/ 23 января 2009

Номер 5 в моем списке из пяти стилей AJAX , как правило, работает довольно хорошо.

0 голосов
/ 11 декабря 2008

Возможно, я не до конца понимаю вашу проблему, но вот как бы я решил ваши требования:

Сортировка, Фильтр

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

Если ваши отчеты разбиты на страницы, я думаю, что будет проще и лучше обновить всю таблицу или страницу.

* Группа 1009 * Я не могу здесь помочь, так как не понимаю, как вы включите группировку. Вы переключаете столбцы, чтобы показать накопления? Как вы показываете данные, которые не поддерживают, накапливается как текст или даты? Новый предмет

На этот раз я бы использовал AJAX с ответом JSON, чтобы подтвердить, что новый элемент был сохранен правильно и, возможно, с вычисленными данными.

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

0 голосов
/ 09 декабря 2008

Как и в обычном программировании на стороне сервера, вы должны стремиться инкапсулировать свои сущности с помощью элементов управления, в вашем случае клиентские элементы управления, которые имеют свойства данных, а также отображают методы + события.

Так, например, скажем, у вас есть на странице объект, который показывает дерево сотрудников, фактически вы должны инкапсулировать его поведение в классе на стороне клиента, который может получить объект JSON из списка сотрудников / по умолчанию подключиться к службе и метод render для вывода вывода, событий и т. д.

В ExtJS создание таких элементов управления сравнительно легко - посмотрите эту статью .

0 голосов
/ 08 декабря 2008

"Возможно, отправить JSON с сервера, но также включить фрагмент HTML в качестве атрибута, чтобы Javascript мог выполнять фильтрацию, сортировку и т. Д., А затем просто вставить данный фрагмент?"

Я рекомендую сохранить уровень представления на клиенте и просто загружать данные по мере необходимости.

Для элементарного движка шаблонов вы можете расширить шаблонную конструкцию Prototype: http://www.prototypejs.org/api/template

Когда ваш клиент масштабируется, и вам нужен богатый и гибкий MVC, попробуйте PureMVC. http://puremvc.org/content/view/102/181/

0 голосов
/ 08 декабря 2008

Кто-нибудь пробовал что-то вроде следующего? Теперь есть избыточные данные, но весь рендеринг выполняется на стороне сервера, а все взаимодействие выполняется на стороне клиента.

Сторона сервера:

render_table_initially:
  if nojs:
    render big_html_table
  else:
    render empty_table_with_callback_to_load_table


load_table:
  render '{ rows: [
    { foo: "a", bar: "b", renderedHTML: "<tr><td>...</td></tr>" },
    { foo: "c", bar: "d", renderedHTML: "<tr><td>...</td></tr>" },
    ...
  ]}'

Клиентская сторона:

dojo.xhrGet({
  url: '/load_table',
  handleAs: 'json',
  load: function(response) {
    dojo.global.all_available_data = response;
    dojo.each(response.rows, function(row) {
      insert_row(row.renderedHTML);
    }
  }
});

Хранение all_available_data позволяет выполнять сортировку, фильтрацию, группировку и т. Д., Не затрагивая сервер.

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

0 голосов
/ 08 декабря 2008

У меня нет полного ответа для вас; Я тоже боролся с этим в недавнем проекте. Но вот мысль:

  • Ajax-вызов Rails
  • Rails снова создает всю сетку с новой строкой.
  • Rails сериализует HTML, который возвращается в браузер.
  • Javascript заменяет весь элемент сетки новым HTML.

Примечание: я не специалист по Rails, поэтому не уверен, что эти биты подходят

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...