使用不显眼的 JavaScript 更新元素
如您所知,当您从 Rails 2 升级到 3 时,您可以将以下内容替换
link_to_remote "more", :url => {...}
为
link_to "more", {...}, :remote => true
:但是如何处理 link_to_remote 中的 :update 选项?在 Railscast #205 中,Ryan Bates 演示了 link_to
和 :remote
和一个服务器响应,其中包含用于更新页面中特定元素的 JavaScript 代码,但这种做法对我来说似乎是错误的。我希望我的服务器的响应是一个简单的 HTML 片段,该片段易于测试并且可以由不同页面(客户端)以不同方式使用。我认为服务器不必知道请求页面上目标元素的 ID,因为它将操作与页面(迷你客户端)联系起来,因此使其不那么通用(它也感觉比纯 HTML 更难看)回复)。
那么,明确地说,有没有办法
link_to_remote "more", :url => {...}, :update => "products-list"
用 Rails 3 和 UJS 来做这样的事情?或者我是否必须编写 JavaScript 来捕获服务器的 HTML 响应并将其插入页面上的正确元素中?
如果是后者,请描述最佳方法(可以使用 link_to
的 :remote
选项吗?)。
As you know, when you upgrade from Rails 2 to 3 you replace this:
link_to_remote "more", :url => {...}
with this:
link_to "more", {...}, :remote => true
But how do you handle the :update option in link_to_remote? In Railscast #205 Ryan Bates demonstrates link_to
with :remote
and a server response that includes JavaScript code to update a particular element in a page, but this practice seems wrong to me. I want my server's response to be a simple HTML fragment which is easy to test and which can be used by different pages (clients) in different ways. I don't think the server should have to know the ID of the target element on the requesting page as it ties the action to the page (a mini-client) and therefore makes it less general (it also feels uglier than a pure HTML response).
So, to be explicit, is there a way to do something like this:
link_to_remote "more", :url => {...}, :update => "products-list"
with Rails 3 and UJS? Or do I have to write JavaScript to capture the server's HTML response and insert it into the right element on the page?
If the latter, please describe the best approach (can link_to
's :remote
option be used at all?).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,您可以使用 link_to :remote 应用后一种方法(编写自定义 JS 来获取服务器响应)。
你也可以选择获取json响应,然后使用JS更新页面上的数据。无论如何,请记住仅渲染部分页面,而不是整个页面。
编辑:
示例代码,这应该在单击 id“more”的内容时进行 AJAX 调用,然后更新页面中的 #product-list 元素:
您不需要更多代码,您可以编写一些帮助程序来生成此 JS ,而不是在视图中编写代码。顺便说一句,这还是 UJS
yes, you can apply the latter approach (write custom JS to get server response) by using link_to :remote.
you can also choose to get a json response, then update data on the page using JS. in any case, remember to render only the partial, not the entire page.
EDIT:
a sample code, this should make AJAX call when clicking something with id "more", then update a #product-list element in the page:
you don't need more code, and you can write some helper to generate this JS, instead of writing code in the view. btw this is yet UJS
在 js 视图
/apps/views/product/index.js.erb
中可以编写 JS 代码,如以下原型:
jquery:
or
,请求成功时会执行
in the js view
/apps/views/product/index.js.erb
you can write JS code such as the followingprototype:
jquery:
or
and it will be executed when the request is successful
我不能 100% 确定这是 Rails 认可的方法,但我找到了一个可行且看起来相当干净的解决方案。假设我们有一个页面列出了数据库中十种最受欢迎的产品。最后是一个通过 AJAX 加载所有剩余产品的链接:
服务器返回纯 HTML(以便该链接可以在许多不同的页面上使用,并且不绑定到特定的 DOM ID)。我们使用 Rails UJS 驱动程序触发的 ajax:x 事件(这里我使用 jQuery)来获取服务器的响应并将其插入到页面上的正确元素中:
如果需要,我们也可以使用
ajax:loading
事件显示“旋转器”:Rails UJS 驱动程序还会触发其他四个事件:
ajax:success
、ajax:failure
代码>、<代码>ajax:之前和<代码>ajax:之后。有关详细信息,请参阅应用程序中包含的驱动程序 (public/javascripts/rails.js)。I'm not 100% sure that this is the Rails-endorsed way to do it, but I've found a solution that works and seems pretty clean. Let's say we have a page that lists the ten most popular products in our database. At the end is a link to load all remaining products via AJAX:
The server returns plain HTML (so that the link can be used on many different pages and is not bound to particular DOM IDs). We use the
ajax:x
events triggered by the Rails UJS drivers (here I'm using jQuery) to grab the server's response and insert it into the right element on the page:If desired, we can also use the
ajax:loading
event to show a "spinner":The Rails UJS drivers trigger four other events as well:
ajax:success
,ajax:failure
,ajax:before
, andajax:after
. See the driver included in your app (public/javascripts/rails.js) for more information.