如何响应AJAX调用没有erb.js /为什么使用erb.js
How to respond_to AJAX call without erb.js / why use erb.js?
最近几天我一直在尝试理解rails上AJAX的不同方面。在阅读了一些介绍之后,我对rails内置的UJS特性有了一些了解。这是我写的一个小玩具应用程序的一个例子,我想在这里介绍一些ajax功能…
控制器动作如下
class ExpenseListsController < ApplicationController
before_action :require_authentication
...
def create
@expense_list = ExpenseList.new(expense_list_params)
if @expense_list.save
respond_to do |format|
format.html do
flash[:success] = 'Created!'
render :show
end
format.js
end
else
respond_to do |format|
format.html do
@errors = @expense_list.errors
flash[:danger] = 'Something went wrong!'
render :new
end
format.js
end
end
end
...
end
在我看来,我通过remote: true
选项调用该操作
各自的create.js.erb
看起来像这样
var form_field = $('.expense_lists_form');
var expenseLists = $('#expense-lists');
expenseLists.append("<%= j render @expense_list %>");
form_field.slideUp(200);
@expense_list
的模板看起来像这样
.col-xs-12.col-lg-3.col-md-4{id: "expense_list_#{expense_list.id}"}
.panel.panel-default
.panel-heading
= link_to expense_list.name, expense_list_path(expense_list)
.panel-body
.links
= link_to 'Modify list', edit_expense_list_path(expense_list), remote: true
= link_to 'Delete list', expense_list_path(expense_list), method: 'delete', remote: true
.description
%p
- if expense_list.description.present?
= expense_list.description
- else
%i
No description supplied, add one
=link_to 'here', edit_expense_list_path(expense_list)
.email-notification.text-muted
(Email notifications enabled)
.panel-footer
= "Expenses in #{current_month_name}:"
%b
= "#{expense_list.sum_of_exp_in_month(current_month, current_year)}€"
= "(#{expense_list.euros_left_in_month(current_month, current_year)}€ left)" if expense_list.budget_in_euro
它工作,但对我来说这个想法似乎有一些缺点:
- 通过额外的*.js使我的文件结构膨胀。erb文件
- 扭曲JS和其余代码库的物理分离 当我使用HAML时,它引入了一种新的编码风格(ERB)
现在我有两个问题:
每个教程(到目前为止我看到的)似乎都在推广这种在Rails中处理AJAX响应的解决方案:为什么?当我检查其他更大的rails项目(例如Diaspora)的代码时,我似乎没有发现他们这样做-他们中的大多数似乎通过
$.ajax({ ... })
在纯JS/jQuery中处理它。那么rails内部UJS方法的主要优点是什么呢?如果由于某种原因rails的ujs方式更受欢迎:你如何组织你的代码?为
*.js.erb
-文件创建额外的目录?将所有这些东西转移到位于我的
/app/assets/javascript
目录的纯javascript文件,并处理jQuery中的AJAX请求,这将是一个很好的做法?我的控制器响应如何看起来像为了响应HTML的适当部分,通过JS更新DOM ?换句话说:我如何用我可以在纯Javascript/jQuery中处理的部分来响应?
提前感谢!安迪
那么rails-内部UJS方法的主要优点是什么呢?
js.erb
是穷人单页架构(SPA)的一种形式。
它使得从控制器返回.js
响应(修改当前页面)非常容易,并允许您使用rails帮助器进行模板,这样您就不必使用客户端模板系统,如车把。
注意,这并不是真正的rails内部。jQuery UJS简单地利用了rails可以返回资源的多种格式的事实。你可以在任何可以使用javascript的MVC框架中使用它。
它的主要优点是非常平易近人。对于那些需要少量ajax的经典同步应用来说,这已经足够了。
它给了那些认为jQuery.load
和脚本标签无处不在是自切片面包以来最好的东西的开发人员足够的绳子来吊死自己。
缺点
- 违反REST,因为
js.erb
视图通常用作操作当前页面的过程。 -
js.erb
视图中的javascript不会因为每个请求的服务而被资产管道最小化。这将导致糟糕的架构决策。
还有什么选择?
早在jquery-ujs
进入场景之前,我们就已经发现做ajax请求的最佳方式是JSON。
如果你想异步发送一个表单你可以这样做:
$(document).on('submit', '.ajax-form', function(e){
e.preventDefault();
var $form = $(this);
var promise = $.ajax($form.attr('action'), {
accepts: { json: 'application/json' },
data: $form.serialize(),
context: $form,
method: $form.attr('method')
});
promise.done(function(response){
// handle the response
});
});
这样就可以将javascript逻辑连接到单个文件中,并在javascript测试工具中单独测试。
你的后端服务器只响应简单的数据,而不关心客户端如何处理它。
然而,这确实需要你在客户端设置一些模板来处理JSON到HTML的转换,你需要设置像数据绑定这样的东西来让你的表单显示错误。这会导致代码重复。
这就是像Ember和Angular这样的SPA框架出现的地方,它们在客户端完成所有的模板和渲染。
我怎么能与部分,我可以在纯Javascript/jQuery处理响应?
你可以创建额外的格式,你的控制器响应。例如,您可以注册一个"text/html-partial"
mime类型。
或者创建额外的路由,甚至使用查询参数(颤栗)。
然而,由于与js.erb
完全相同的原因,这不是理想的-它导致一个蹩脚的API,因为你的控制器将成为进程而不是面向资源的。您最终将创建荒谬的控制器动作,只是为了将html片段传递回客户端。
- Rails 3.2 js.erb文件转义js
- Js.erb VS按钮标记-不'不起作用.为什么?
- js.erb文件未呈现其内容
- 如何使用 Ruby 在 Javascript (js.erb) 中设置 url
- Rails:如何在jQuery(.js.erb)中调用“create”操作
- js erb 内的 Rails 会话为空
- 在Rails中使用remote:true在Chrome中有效,但在Safari中无效——从js.erb文件调用succe
- js.erb文件中提供给RegExp构造函数的标志无效
- 如何在我的create.js.erb中重置/清除表单
- Rails js.erb文件未执行
- js.erb格式的控制器测试
- 使用控制器在conditional.js.erb文件中设置变量
- 我的 update.js.erb 文件仅在第一次单击按钮时运行,而不在后续单击时运行(单击时更改按钮的类和值)
- 在 Ajax 中创建 RoR 链接 在 .js.erb 文件中调用
- Rails 3 嵌入式小部件:show.js.erb 似乎不起作用
- js.erb 呈现到布局中,而不是执行
- 将变量传递给 js.erb 文件
- Ruby on Rails 在 js.erb 中渲染 json
- 如何在 js.erb 中删除 “ 以渲染 JavaScript Rails
- 如何在 Rails 3 上从 js.erb 调用 coffeescript 函数以及如何理解 Javascript 中的