干掉路由和 JavaScript 响应

发布于 2024-08-06 11:35:38 字数 1296 浏览 6 评论 0原文

我不确定我是否缺少已知的设计模式,但我不断遇到 RESTful 路线 Rails 的以下问题。

在我的示例中,我有一个可以以 javascript (:js) 格式响应的用户控制器。默认响应使用分页用户列表填充页面元素:

# /app/controllers/users_controller.rb
class UsersController < ActionController
  def index
    @users = User.paginate(:all, :page => params[:page], :conditions => ['name ILIKE ?', params[:name])

    respond_to do |format|
      format.html
      format.js
    end
  end
end

相应的 RJS 模板如下所示:

# /app/views/users/index.js.rjs
page.replace_html :users, :partial => 'users'

这工作正常,允许我对用户执行 AJAX 查找。但是,在我网站的另一部分(例如用户编辑表单),我想执行用户的 AJAX 查找,但更新一组“选择”选项或执行内联自动完成,而不是更新 #users 页面元素,例如

# /app/views/users/edit.html.erb
<%= f.text_field :name %>
$('#user_name').autocomplete({url: '/users', data: 'name=value', ...})

我的问题是实现这一目标的最佳 DRY 方法是什么?我认为我不需要创建一个新的控制器操作来对应不同的视图,因为这将涉及重复查找器代码。到目前为止,我遇到的唯一解决方案是在我的 RJS 帮助器中构建一些 javascript 条件:

# /app/views/users/index.js.rjs
page << "if($('#users').length > 0)"
  page.replace_html :users, :partial => 'users'
page << "else"
  page.replace_html :user_options, :partial => 'user_options_for_select'

这感觉非常脆弱,并且对于 Rails 来说不干净。我是否遗漏了如何根据调用控制器以不同的视图进行响应?

感谢任何帮助! 克里斯

I'm not sure if I'm missing a known design pattern, but I keep coming up against the following problem with RESTful routes Rails.

In my example, I have a users controller that can respond in javascript (:js) format. The default response populates a page element with a list of the paginated users:

# /app/controllers/users_controller.rb
class UsersController < ActionController
  def index
    @users = User.paginate(:all, :page => params[:page], :conditions => ['name ILIKE ?', params[:name])

    respond_to do |format|
      format.html
      format.js
    end
  end
end

The corresponding RJS template would look like:

# /app/views/users/index.js.rjs
page.replace_html :users, :partial => 'users'

This works fine, allowing me to perform AJAX lookups on users. However, in another part of my site (say the user editing form) I would like to perform an AJAX lookup of users, but update a set of ''select'' options or perform an inline autocomplete, rather than update the #users page element, e.g.

# /app/views/users/edit.html.erb
<%= f.text_field :name %>
$('#user_name').autocomplete({url: '/users', data: 'name=value', ...})

My question is what would be the best DRY way to achieve this? I don't think I should need to create a new controller action to correspond to the different view, as this would involve repeating the finder code. The only solution I've come across so far is to build some javascript conditions into my RJS helper:

# /app/views/users/index.js.rjs
page << "if($('#users').length > 0)"
  page.replace_html :users, :partial => 'users'
page << "else"
  page.replace_html :user_options, :partial => 'user_options_for_select'

This feels very brittle, and unclean for Rails. Am I missing something in how I can respond with different views depending on the calling controller?

Appreciate any help!
Chris

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

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

发布评论

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

评论(1

月棠 2024-08-13 11:35:38

其中一个是用户列表,另一个是选项列表。
因此,即使现在您的两个页面具有相同的功能,但它们彼此独立,您将来可能只想更改其中一个页面的内容。

所以我会用两个不同的 javascript 操作来区分它们。它将让你更容易地让他们在不同的道路上进化。

无论如何,正如你所看到的,它们已经完全不同了。您有两个不同的部分和两个不同的 html 标签 id。
尝试在这里为它们使用相同的代码对我来说似乎很困惑。

所以是的,我会创建两个操作,一个用于用户列表,一个用于他们的选项。

In one of them you have a list of users and the other one a list of options.
So even though for now, your two pages are having the same feature, they're independent from each other and you might want to change things for only one of them in the future.

So I'd keep them distinct with two different javascript actions . It'll will allow you to much more easily make them evoluate on their different path.

Anyway as you can see, they're already quite different. You have two different partials and two different html tags id.
Trying to have the same code for them both here seems quite confusing to me.

So yes I'd create two actions, one for the users list and one for their options.

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