0

在我当前的项目中,我有几个实例,其中我有一个可重用的表单,它存在于 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。将一些参数从 post_detail.erb 传递给 _comments_box.erb 到 _comments_box.erb 部分,以便它知道要触发哪个控制器方法。这将允许我拥有一个单独的文件 _create_2.js.erb,这将允许我独立操作 post_detail.erb 视图。
  • 完全忘记使用 js.erb,只使用普通的旧 AJAX 并返回 JSON,并在客户端完全处理 javascript 操作。

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

4

3 回答 3

3

这正是目的Apotomohttp ://apotomo.de/

这是它自己的描述:

Apotomo 是一个真正的用于 Rails 的 MVC 小部件框架。小部件基于 Cells 并提供可重用的视图组件。通过冒泡事件,他们知道何时以及如何通过 AJAX 更新自己!

使用 Apotomo 小部件几乎就像在 Rails 环境中开发 GUI 组件一样。

试试看,很棒。

于 2011-05-15T16:07:41.980 回答
2

我不建议将 UJS 用于前端应用程序:服务器不应该处理客户端业务。我同意它有用且干净,但它缺乏性能,因此应该保留用于后端的东西(RJS 将变成一个 gem,见这里:http ://weblog.rubyonrails.org/2011/4/21/jquery-new-default )。

也就是说,回到您公开的解决方案:

  • 1)我认为你不需要额外的控制器,你只需要传递额外的参数就可以知道查询的来源。Ahidden_field可以做到这一点。有了这个信息,渲染好的js.erb文件

    format.js { if condition
                 render "create.js.erb"
                else
                  render "create_2.js.erb"
                end
              }
    
  • 2)我会去它并返回 json 但你会面临同样的问题:知道请求来自哪里。

于 2011-05-17T22:29:20.543 回答
2

更好的解决方案(比使用 a hidden_field)可能是检查request.referer控制器动作。通过这种方式,您可以利用每个上下文都有一个唯一 URL 的事实,并且在呈现您的小部件部分时不必显式指定另一个唯一值。

于 2011-05-18T05:22:01.810 回答