Rails 3.2 的 Ajax 向导
2014-01-12 17:40
405 查看
21 Apr 2012
Rails 3.2 的 Ajax 向导
转自:http://chloerei.com/2012/04/21/rails-3-2-ajax-guide/前不久入手了《Web开发敏捷之道》的中文第4版,翻看了 Ajax 部分,发现竟然还是使用 .rjs 模板。.rjs 模板在 3.1 版以后已经被移除。另外我又去看了官方的 Rails guide,发现也没有讲述 Ajax
的章节。
也就是说新手入门的时候,可能会搞不清楚 Rails 如何实现 Ajax,所以我写了这篇向导。
Ajax 是什么?
原生的网页浏览方式是通过超链接,每点击一个链接,浏览器会从服务端下载完整的网页并更新用户看到的内容,这样用户会看到短暂的白页或者闪烁。Ajax 提供了一种浏览器和服务端的异步交互方式,实现无刷新页面的情况下更新页面。明白 Ajax 的目的之后,我们来看如何在 Rails 里面实现 Ajax。
Rails Ajax 的两种类型
在 Rails 里面处理 Ajax 大致可以分为两种:UJS:服务端返回 Javascript,客户端收到后直接执行
JSON API:服务端返回数据,客户端收到后本地处理再执行
Rails 自带的 UJS 机制在提供少量 AJAX 操作的时候很便利。如果你只想写 Javascript 原生的 Ajax,或者需要为客户端应用提供 API,那么应该了解 JSON API 方式。
UJS
先看一段代码,这是一个常见的回复表单:<%= form_for @reply do |f| %> <%= f.text_area :body %> <% end %>
对应的 action 如下:
# POST /replies def create @reply = @topic.replies.new params[:reply].merge(:user => current_user) if @reply.save redirect_to @topic else render :new end end
创建回复的时候,如果成功,服务端会要求重定向到话题页面,如果不成功,服务器会渲染
:new页面,让用户再次编辑。
现在用 UJS 方式改写它,回复成功的时候,将回复添加到页面回复列表的后面,否则显示一条错误信息。
首先,为表单添加一个
:remote参数:
<%= form_for @reply, :remote => true do |f| %> <%= f.text_area :body %> <% end %>
将
:remote设置为
true后,Rails 的
form_forhelper 会插入一个
data-remote=true属性,这样它自带的
rails_ujs.js模块会自动为这个表单开启 UJS 方式的 Ajax。如果你想知道这魔法是怎么实现的,可以去看看 jquery-ujs 的源码。
然后,在对应 action 里加上
respond_to和
format.js代码块:
# POST /replies def create @reply = @topic.replies.new params[:reply].merge(:user => current_user) respond_to do |format| # <- 这里 if @reply.save format.html { redirect_to @topic } format.js # <- 这里 else format.html { render :new } format.js # <- 还有这里 end end end
加入 respond_to 代码块后,Rails 会分辨客户端请求格式是 html 还是 js,不同格式请求返回不同的内容。这里的
format.js表示请求 js 格式的时候按照约定渲染名为
create.js.erb的模板。
最后,添加一个 create.js.erb 模板:
<% if @reply.errors.empty? %> $('<%= j(render :partial => 'reply', :object => @reply) %>').appendTo($('#replies')); <% else %> alert('@reply.errors.full_messages.join(',')'); <% end %>
这个模板区分了 @reply 保存成功和失败的两种情况,保存成功的时候,新回复会被添加到回复列表的后面,否则会弹出一条错误信息。
JSON API
UJS 的好处是代码量少,可以复用服务端的模板,但不适用于重客户端的场景。现在来看 Rails 提供 JSON API 的方法。修改 action,添加
format.json:
# POST /replies def create @reply = @topic.replies.new params[:reply].merge(:user => current_user) respond_to do |format| if @reply.save format.html { redirect_to @topic } format.js { render :layout => false } format.json { render :json => @reply } # <- 这里 else format.html { render :new } format.js { render :layout => false, :status => 406 } format.json { render :json => {:errors => @reply.errors.full_messages.join(',')} } # <- 还有这里 else end end end
添加这两行后,这个 action 就能处理 JSON 请求了。这个例子没有涉及 API 数据结构设计,如果你需要调整所返回的 JSON 数据的结构,我推荐 jbuilder 模板。
2013-11-19 更新:jbuilder 是 Rails 4 默认带的 gem。
假设我们用 jQuery.ajax 实现客户端逻辑,那么会有类似代码:
$('new_reply_form').on('submit', function(event){ $.ajax({ url: $(this).prop('action'), dataType: 'json' }).done(function(data) { /* 本地逻辑 */ }); })
.donecallback 中获取的
data就是 JSON API 返回的数据。
该用哪种实现?
如果网站以后端为主,只需要简单的 Ajax 页面更新操作,那么适用 UJS。如果是从前端框架起步,打算搭建重客户端应用,那么适用 JSON API。希望这篇日志有助你了解 Rails 的 Ajax : P
Rei
相关文章推荐
- Rails 3.2 的 Ajax 向导
- Rails 3.2 的 Ajax 向导(非常好)
- rails3.2与ajax
- rails ajax utf-8 error
- some Rails leanrning:Rails Ajax,Validates,Cycle
- [Ruby on Rails实战圣经]Ajax 应用程式
- rails使用ajax实现无刷新二级级联菜单
- [AWDwR4] Getting AJAX to work in Rails 3 with jQuery
- rails应用ajax之三:进一步完善ajax动画特效果
- 在Ruby on Rails中使用AJAX的教程
- AJAX file uploads in Rails using attachment_fu and responds_to_parent 1
- "ruby on rails" with "ajax"
- rails应用ajax之一:使用纯js方法
- rails应用ajax之三:进一步完善ajax动画特效果
- Rails 3.2 新特性简介
- rails中开启了csrf防御如何使用jquery的ajax请求
- RAILS AJAX
- rails3.2 中的 carrierwave 的快速开发
- AJAX file uploads in Rails using attachment_fu and responds_to_parent2
- AJAX file uploads in Rails using attachment_fu and responds_to_parent