在我目前的项目中,我有几个实例,我有一个可重复使用的表单,存在于rails部分内。此表单通过ajax(:remote => true)提交给特定控制器。控制器执行一些操作,然后返回相应的js.erb以通过javascript修改页面。
当我有一个视图时,这可以正常工作。但是,当多个视图中存在可重用的部分时,问题似乎就会发生。在视图1中,我可能想在视图2中发出一组完全不同的javascript命令。
作为一个具体的例子,假设我有一个具有正常CRUD操作的注释控制器。
我现在有部分名为_comments_box.erb。此_comments_box.erb包含通过简单的行提交评论的功能:
- form_for comment, :url => post_comments_path(post), :remote => true do |f|
这提交了一个comments_controller.rb创建方法,它看起来像这样:
def create
... do some stuff, like create a new comments model
respond_to do |format|
# will respond with create.js.erb
format.js
end
end
create.js.erb反过来向视图添加注释,可能会对DOM进行一系列其他更新。
假设我在名为post_summary.erb的视图中渲染_comments_box.erb。现在我有另一个视图,post_detail.erb需要相同的_comments_box.erb。但是post_detail.erb要求我更新DOM上完全不同的div以响应新的评论。
我需要为每个实例创建一个不同的JS响应。所以我可以:
似乎选项1允许我继续使用Rails支持的UJS,这很好。但也意味着我可能会在任何地方添加很多重复的代码,这很烦人。在继续使用UJS的同时,我有办法优雅地做到这一点吗?
答案 0 :(得分:3)
这正是Apotomo
:http://apotomo.de/
这是它自己的描述:
Apotomo是一个真正的MVC小部件框架 对于Rails。小部件基于单元格 并提供可重复使用的视图组件。 冒泡的事件,他们知道什么时候 以及如何通过AJAX更新自己!
几乎与Apotomo小部件合作 感觉就像开发GUI组件 - 在Rails环境中。
试一试,这很棒。
答案 1 :(得分:2)
我不建议将UJS用于前端应用程序:服务器不应该处理客户端业务。我同意它有用且干净,但缺乏性能,因此应保留后端内容(RJS将移入宝石,请参见此处:http://weblog.rubyonrails.org/2011/4/21/jquery-new-default)。
那说,回到你揭露的解决方案:
1)我认为你不需要一个额外的控制器,你只需要传递额外的参数,以便知道查询的来源。 hidden_field
可以做到这一点。使用此信息,呈现好的js.erb
文件
format.js { if condition
render "create.js.erb"
else
render "create_2.js.erb"
end
}
2)我会去找它并返回json,但你会遇到同样的问题:知道请求来自何处。
答案 2 :(得分:2)
更好的解决方案(使用hidden_field
)可能是检查控制器操作中的request.referer
。通过这种方式,您可以利用每个上下文都具有唯一URL的事实,并且在将窗口小部件呈现为部分时不必显式指定另一个唯一值。