在我当前的项目中,我有几个实例,其中我有一个可重用的表单,它存在于 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 的同时优雅地做到这一点?