当您拥有可重复使用的小部件时,在轨道中执行UJS的最佳方法是什么?

时间:2011-05-11 05:58:51

标签: ruby-on-rails ruby-on-rails-3 partials ujs

在我目前的项目中,我有几个实例,我有一个可重复使用的表单,存在于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响应。所以我可以:

  • 创建备用控制器方法,例如create_2。将一些参数传递给_comments_box.erb,从post_detail.erb传递到_comments_box.erb部分,以便它知道要触发哪个控制器方法。这将允许我有一个单独的文件_create_2.js.erb,它允许我独立地操作post_detail.erb视图。
  • 忘记完全使用js.erb并只使用普通的旧AJAX并返回JSON,并在客户端完全处理javascript操作。

似乎选项1允许我继续使用Rails支持的UJS,这很好。但也意味着我可能会在任何地方添加很多重复的代码,这很烦人。在继续使用UJS的同时,我有办法优雅地做到这一点吗?

3 个答案:

答案 0 :(得分:3)

这正是Apotomohttp://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的事实,并且在将窗口小部件呈现为部分时不必显式指定另一个唯一值。