Rails AJAX 使用 format.js 和 format.json 的区别以及问题

chaucerling · 2015年11月05日 · 最后由 rei 回复于 2015年11月09日 · 3836 次阅读
def update
  @product = product.find(params[:id])
  respond_to do |format|                                            
    if @product.update(product_params)
      format.html { redirect_to @product } 
      format.js
      format.json { render json: @product, status: :accepted }
    else
      format.html { render action: "edit" }
      format.js
      format.json { render json: @product.errors, status: :unprocessable_entity }
    end
  end
end
// update.js.erb
<% if @product.errors.any? %>
  $('#alert').show()
  $('#alert-content').html('<%= @product.errors.join(', ')%>')
<% else %>
  $('#product_<%= @product.id %>').replaceWith('<%= j render(@product) %>');
<% end %>
  • format.js 返回的是浏览器可执行的 js 代码,一般是把渲染好的 html 片段对页面元素做替换或者增添
  • format.json 返回的是 json 数据,需要前端操作 dom 对 view 进行修改
  • 对于有大量属性和复杂结构的页面,format.js 有优势,因为后端只要对一个模版进行渲染即可,而 format.json 需要写大量 dom 操作,而且 view 页面上要加上很多的 id
  • 状态判断,format.js 是后端根据业务逻辑生成不同操作的 js 代码让浏览器执行(应该也可以前端根据返回码操作),format.json 是根据返回码判断请求是否成功,然后再对返回对结果作处理

我觉得使用 format.js 的优点是可以减少对 dom 的操作,但对每一个 action 都要新建不同的 view,显得有点零碎。而 format.json 的优点是纯前端处理,数据传输量少,但要自己写很多的 dom 操作。

我之前也写过一点 ember,如果只是在 app 上做简单的 ajax,而不是做 spa,ember 显得太重了

不知道有什么 gem 或者轻量的前端框架能结合两者的优点?

我感觉是优先用 format.html,有少量动态需求用 format.js。一旦觉得写 format.js 烦躁了,应该改用 format.json,搭配好的前端框架。

Rails 鼓励使用 format.js,因为渲染的 html 可以同后端共享,rails_ujs,turbolink 的支持也好。当然缺点也明显,前端后端不分离,完全的 Rails 解决方案绑定,后期不利于进行 micro-service 化。

format.json 的话,必然搭配前端框架,ember 配ams其实是目前成熟度最高的,也是除了除了 format.js 最偏 rails 的,其实越是纯 json,对 rails 的依赖越少,其实用 rails 的意义就越小。

format.json 对前端框架的选择,react-rails或者vue.js,目前是比较火的,但是就没有 ams 这样的 declative gems 了,一般都需要用 jbuilder 进行输出。

#2 楼 @ericguo vue.js 稍微看过文档,但我觉得不是要做 spa,只是要做简单的数据绑定,舍弃 rails 的 view 层,引入前端框架去接管是否值得?

我觉得是不是要基于业务呢,rails-api 可以去掉 views 的渲染,从而提高效率

format.js 和朋友讨论了,也是前后不分

format.json 搭配前端框架就是需要为扩展做准备

一切业务决定方案

#3 楼 @chaucerling 当然不值得,不过现实的问题是先有了简单的页面 DOM 更新,然后你就会碰到复杂的,然后越搞越复杂,直到某一个点,你强烈的感到其实这已经是 SPA 了。。。

尽量用 Rails 默认栈,碰到瓶颈了再考虑其它方案。看 Basecamp 3 的跨平台实现可以知道,Rails 默认栈是很有想象力的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号