在 Iteration F2 中,按照书上的改法,单击Add Cart之后,页面没有丝毫反应。看后台有错如下:
Completed 500 Internal Server Error in 12msActionView::MissingTemplate (Missing template line_items/create, application/create with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/csd/railsProjects/depot/app/views"): app/controllers/line_items_controller.rb:55:in `create' Rendered /usr/local/rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/missing_template.erb within rescues/layout (0.5ms)
上网搜索,发现是由于
导致找不到 create.js.erb模板。如果想使用JQuery而非 RJS,解决方法如下:
step1. 把 app/views/line_items/create.js.rjs 文件改名为 app/views/line_items/create.js.erb。
step2. 用如下的内容替换app/views/line_items/create.js.rjs 的内容:$('#cart').html("<%= escape_javascript(render(@cart)) %>");
- $('#cart')用jQuery 语法来选中 id为 cart的元素, 然后将其内容赋值为 render(@cart)。
- escape_javascript 会将回车,单,双引号进行转义处理。
修改完成后再次单击 Add to cart 按钮,此时可以看到左边的列表自动更新了,服务器端日志如下:
Rendered line_items/_line_item.html.erb (4.8ms) Rendered carts/_cart.html.erb (8.3ms) Rendered line_items/create.js.erb (10.4ms) Completed 200 OK in 24ms (Views: 12.4ms | ActiveRecord: 3.9ms)
PS:由于在 app/views/store/index.html.erb 中的 button_to 中有参数 :remote => true, 所以 浏览器会发送 Ajax 请求到服务器端(Ajax请求dataType默认是script,即要服务器端返回JavaScript格式的数据)。在app/controllers/line_items_controller.rb 中 create action 中有如下代码:
respond_to do |format| if @line_item.save format.html { redirect_to store_url} format.js format.json { render json: @line_item, status: :created, location: @line_item } else format.html { render action: "new" } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end
respond_to里面的代码执行逻辑如下: 当@line_item保存到数据库成功,如果客户端要求返回的是html格式,则重定向到store页面,如果客户端要求返回的是js格式,则默认渲染(format.js 之后没有 block 来指定操作) 与此action(create)关联的JavaScript模板(create.js.erb)。参考 。
PS:如果使用的是火狐浏览器,可以使用强大的插件来调试,在网络->XHR 标签页中可以实时地看到客户端的Ajax 请求和服务器端的响应。
参考文章:
可以学习 Rails 3.2 的 Ajax 向导 http://chloerei.com/2012/04/21/rails-3-2-ajax-guide/