当你有一个可重用的小部件时,在 Rails 中执行 UJS 的最佳方法是什么?

发布于 2024-11-06 08:27:56 字数 1288 浏览 1 评论 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 的同时优雅地做到这一点?

In my current project I have a couple instances where I have a re-usable form that exists inside a rails partial. This form submits to a specific controller via ajax (:remote => true). The controller does some stuff and then returns back the appropriate js.erb to modify the page via javascript.

This works fine for when I have a single view. But the problem seems to happen when this re-usable partial exists on multiple views. In view 1 I might want to issue a completely different set of javascript commands then in view 2.

As a concrete example, say I have a comments controller that has the normal CRUD operations.

I now have partial called _comments_box.erb. This _comments_box.erb contains the ability to submit a comment via a simple line:

- form_for comment, :url => post_comments_path(post), :remote => true do |f|

This submits to a comments_controller.rb create method which looks somethings like this:

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

The create.js.erb in turn adds a comment to the view, perhaps doing a bunch of other updates to the DOM.

Say I render the _comments_box.erb within a view called post_summary.erb. Now I have another view, post_detail.erb that requires the same _comments_box.erb. However the post_detail.erb requires me to update completely different divs on the DOM in response to a new comment.

I need to create a different JS response for each instantiation. So I can either:

  • Create an alternate controller method, say create_2. Pass in some parameter to the _comments_box.erb from post_detail.erb to the _comments_box.erb partial so it knows which controller method to fire. This will allow me to have a separate file _create_2.js.erb that will allow me to manipulate the post_detail.erb view independently.
  • Forget about using js.erb altogether and just use plain old AJAX and get back JSON, and handle the javascript manipulation completely on the client-side.

It seems option 1 allows me to continue to use the UJS supported by Rails which is nice. But also means I probably will be adding a lot of duplicate code everywhere which is annoying. Is there a way for me to do this elegantly while continuing to use UJS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

め可乐爱微笑 2024-11-13 08:27:56

这正是 Apotomo 的目的:http://apotomo.de/

这是它自己的描述:

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

几乎可以使用 Apotomo 小部件
感觉就像开发 GUI 组件 –
在 Rails 环境中。

尝试一下,很棒。

That's exactly the purpose of Apotomo: http://apotomo.de/

Here is it's own description:

Apotomo is a true MVC widget framework
for Rails. Widgets are based on Cells
and provide reuseable view components.
Having bubbling events, they know when
and how to update themselves via AJAX!

Working with Apotomo widgets almost
feels like developing GUI components –
in a Rails environment.

Have a try, it's great.

凉月流沐 2024-11-13 08:27:56

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

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

  • 1)我认为您不需要额外的控制器,您只需传递额外的参数即可知道查询来自哪里。 hidden_​​field 可以解决这个问题。有了这些信息,渲染好的 js.erb 文件

    format.js { if 条件
                 渲染“create.js.erb”
                别的
                  渲染“create_2.js.erb”
                结尾
              }
    
  • 2) 我会选择它并返回 json,但您将面临同样的问题:知道请求来自哪里。< /p>

I'd not recommend using UJS for frontend apps: server shouldn't take care of client side business. I agree it's useful and clean but it lacks performance and thus should be kept for backend stuff (RJS will move into a gem, see here: http://weblog.rubyonrails.org/2011/4/21/jquery-new-default).

That said, back to the solutions you expose:

  • 1) I think you won't need an extra controller, you'd just have to pass additional params in order to know from where to query came from. A hidden_field could do the trick. With this info, render the good js.erb file

    format.js { if condition
                 render "create.js.erb"
                else
                  render "create_2.js.erb"
                end
              }
    
  • 2) I'd go for it and return json but you'll face the same problem: knowing from where the request comes from.

○愚か者の日 2024-11-13 08:27:56

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

A better solution (than using a hidden_field) might be to check the request.referer in your controller action. This way you leverage the fact that each context has a unique URL, and don't have to explicitly specify another unique value when rendering your widget partial.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文