JSON Templating - PullRequest
       2

JSON Templating

3 голосов
/ 16 июня 2011

В качестве предыстории я нахожусь на ранних стадиях разработки большого проекта RoR для компании, в которой я работаю, и мы планируем придерживаться Rails в течение следующих 5-10 лет.На данный момент мы находимся в проекте, где пытаемся получить полезные практики и настроить фреймворк, чтобы он работал в соответствии с нашими потребностями.Мы рассмотрели все плюсы и минусы создания полноценного веб-приложения (стиль Backbone.js) по сравнению со статическим ограниченным приложением Rails на основе JS.Хотя мы хотели бы использовать веб-приложение, я решил, что использование Backbone.js приведет к:

  • Полному дублированию представлений и маршрутов (проблема обслуживания в долгосрочной перспективе)
  • Сложность отслеживания полиморфных ассоциаций и их маршрутов
  • Не позволили бы нам использовать помощники вида на стороне клиента (проблема обслуживания)
  • Дублирование некоторой информации о модели
  • Медленные компьютеры на стороне клиента (вне нашего контроля), которые будут испытывать трудности при его запуске

Чтобы попытаться уменьшить это, мы решили пойти на более гибридный подход, но настойчивобольше логики на стороне сервера, при этом поддерживая архитектуру RESTFUL как API как можно лучше.Мы планируем, чтобы начальные загрузки страницы выполнялись в обычном режиме с использованием Rails, а затем любые манипуляции на странице отправляют запрос через AJAX и получают обратно объект JSON, который содержит отрендеренную частичную часть и некоторую дополнительную информацию (например, флэш-обновления, JSON).представление объекта, дополнительные JS включает, если необходимо, и т. д.)

Проблема, с которой мы сталкиваемся, заключается в том, что, насколько я понимаю, мы не можем поддерживать архитектуру RESTFUL и иметь несколько партиалов / представлений для одних и тех же данных.,Как пример этого, если бы я хотел запросить список заказов с сервера через заказы / индексы, он вернул бы только одно представление данных.Если бы у меня была расширенная таблица, список или какой-то другой вид / частичный / виджет, для которого я хотел, чтобы запрошенное частичное было использовано.

Для этого я добавил параметр [: частичный] (которая является либо надстройкой на маршруте, либо параметром url), которая предоставляет серверу как запрашиваемую информацию, так и представление, которое я ожидаю получить. Это будет работать само по себеОднако я также хотел бы, чтобы с сервера одновременно отправлялась дополнительная информация (например, флэш-обновления, представление данных в формате JSON и т. д.).В идеале мы хотим, чтобы это было гибким, быстрым и передавалось с сервера в формате JSON.

С этой целью я переписал существующий JSON-ответчик следующим образом, и вы можете заметить, что мой взломпришлось использовать для отображения шаблонов HAML / ERB внутри JSON:

module ExtraFunctions
 def partial_options
   params.include?(:partial) ? { :partial => params[:partial] } : {}
 end

 def flash_options
   { :file => 'layouts/_flash.html.haml' }
 end
end

ApplicationController.send :include, ExtraFunctions

#I would love to be using the ERB templating and views
#instead of this kludge.  But this will have to do.

ActionController::Renderers.add :json do |json, options|

 #Change the format so we can render the html templates
 self.formats = [:html]
 options = { :layout => false }

 partial_opt = options.merge(self.respond_to?(:partial_options) ? self.partial_options : {})
 flash_opt   = options.merge(self.respond_to?(:flash_options) ? self.flash_options : {})

 obj = {
   json: json.as_json,
   partial: render_to_string(partial_opt),
   flash: flash,
   flash_partial: render_to_string(flash_opt),
   user: @current_user
   #js-includes: #Working on this
 }


 #Change the format back
 self.formats = [:json]

 json = obj.to_json(options) unless obj.kind_of?(String)
 json = "#{options[:callback]}(#{json})" unless options[:callback].blank?

 self.content_type ||= Mime::JSON
 json
end

Вы заметите, что там есть место для js-includes, причина в том, что я хочувозможность динамически включать в конце игры с помощью head.js.Это было бы для более простого управления зависимостями, поскольку начальное представление не будет включать в себя некоторые из частичек, которые запрашиваются через AJAX (т. Е. Если я взял форму для ввода нового адреса, и эта форма имеет некоторую проверку AJAX, как включенав верхней части, используя тег content_for).В идеале, мне бы очень хотелось, чтобы это был JSON-макет, который будет выглядеть примерно так (хотя я надеюсь, что с синтаксисом, более покрытым сахаром):

** json/application.json.erb **
{
   json: <%= json.as_json %>,
   partial: <%= render_to_string(partial_opt) %>,
   flash: <%= flash %>,
   flash_partial: <%= render_to_string(flash_opt) %>,
   user: <%= @current_user =>,
   js-includes: <%= yield :js_includes %>,
   <%= yield =>
}

Я работал над этими соображениями /проблемы на некоторое время, и у меня два вопроса:

1) Есть ли что-то вопиюще глупое в том, что мы делаем?Есть ли лучшее или более стандартное решение?

2) Есть ли способ заставить ERB отображать шаблоны для JSON?

Спасибо!

1 Ответ

1 голос
/ 16 июня 2011

Суть в том, что это общая проблема, которая пока не имеет четкого мнения о решении.

Дэвид Хайнемайер Ханссон немного рассказал об этой проблеме на RailsConf 2011, когда представил новый конвейер активов в Rails 3.1, отметив, что они начали использовать то, что они называют pjax , для обработки обновляющихся частей.страницы и предположил, что это будет частью Rails во времени.

37signals также создала Cinco (среду для мобильных приложений all-js) и планировала открыть его с открытым исходным кодом, но я считаю, что они начали отходить от некоторых идей, которые они создавали, поэтому яне знаю, каков статус.

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