JSON模板

时间:2011-06-16 02:00:12

标签: javascript ruby-on-rails ruby ajax json

作为一个背景,我正处于大型RoR的早期设计阶段 我工作的公司的项目,我们正计划坚持 未来5 - 10年的路轨。我们正处于项目的这一阶段 我们正试图获得一些好的做法并自定义框架 为我们需要的东西工作。我们考虑过了 与一个完整的网络应用程序(Backbone.js风格)相比的优点/缺点 静态有限的基于JS的Rails应用程序。虽然我们本来喜欢去 使用webapp,我已经确定使用Backbone.js会 造成:

  • 完整复制视图和路径(从长远来看是一个维护问题)
  • 难以跟踪多态关联及其路线
  • 不允许我们在客户端使用视图助手 (维修问题)
  • 复制某些模型信息
  • 缓慢的客户端计算机(我们无法控制),这将是 难以运行

为了尝试减少这种情况,我们决定采用更混合的方式 方法,但将更多的逻辑推回到服务器端 仍然将RESTFUL架构作为API保持最佳状态 可能。我们计划完成初始页面加载 通常使用Rails,然后页面上的任何操作发送 请求通过AJAX并接收一个包含的JSON对象 渲染部分,以及一些其他信息(即闪存更新, 对象的JSON表示,附加JS包括if 必要等等。)

我们遇到的问题是,根据我的理解,我们 无法维护RESTFUL架构并且具有多个架构 相同数据的部分/视图。作为一个例子,如果我想 通过订单/索引从服务器请求订单列表,它会 只返回一个数据视图。如果我有一个扩展表,一个列表, 或者我想要的部分其他视图/部分/小部件 用于。

为此,我添加了一个参数[:partial](这是一个附加组件 在路由或url参数上提供服务器 正在请求的信息,以及我的观点 我希望它能够进入。但是,这本身就可以很好地发挥作用 我还希望从中发送任何其他信息 服务器同时(即闪存更新,JSON表示) 数据等)。理想情况下,我们希望这是灵活,快速和发送的 来自服务器的JSON格式。

为此,我已经覆盖了现有的JSON响应器,如下所示, 你可能会注意到我必须使用它来渲染它 JSON中的HAML / ERB模板:

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 个答案:

答案 0 :(得分:1)

最重要的是,这是一个普遍的问题,对解决方案还没有强烈的意见。

David Heinemeier Hansson在RailsConf 2011中谈到了这个问题,他在Rails 3.1中引入了新的Asset Pipeline,并指出他们已经开始使用他们所谓的pjax来处理页面的刷新部分并建议它会及时成为Rails的一部分。

37signals还建立了Cinco(all-js移动应用程序框架),并计划开源,但我相信他们已经开始逐渐远离他们正在构建它的一些想法,所以我不这样做知道状态是什么。