繁体   English   中英

如何在没有erb.js的情况下响应AJAX调用/为什么使用erb.js?

[英]How to respond_to AJAX call without erb.js / why use erb.js?

最近几天,我花了很多时间来理解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)

现在我有两个问题:

  1. 每个教程(到目前为止,我都看过)似乎都在推广这种在Rails中处理AJAX响应的解决方案:为什么? 当我检查其他较大的Rails项目(例如Diaspora)的代码时,我似乎没有发现它们是这样做的-大多数对象似乎都通过$.ajax({ ... })在纯JS / jQuery中处理它$.ajax({ ... }) 那么,内部使用Rails的UJS方法的主要优点是什么?

  2. 如果出于某些原因,最好使用Rails UJS-way:如何组织代码? *.js.erb -files创建额外的目录吗?

  3. 将所有这些内容传输到我的/app/assets/javascript目录中的纯javascript文件并在jQuery中处理AJAX请求的最佳实践是什么? 为了通过HTML的适当部分进行响应以通过JS更新DOM,我的控制器响应将如何显示? 换句话说:我该如何响应我可以在Plain Javascript / jQuery中处理的部分内容?

提前致谢! 和我

那么,内部使用Rails的UJS方法的主要优点是什么?

js.erb是穷人的单页体系结构(SPA)的一种形式。

它很容易从控制器返回.js响应,从而修改当前页面,并允许您使用rails helper进行模板制作,因此您不必使用客户端模板制作系统(如把手)。

请注意,这并不是Rails真正的内部功能。 jQuery UJS简单地使用了Rails可以返回资源的多种格式的事实。 您可以将其与任何可以使用javascript的MVC框架一起使用。

主要优点是它非常平易近人。 对于经典的同步应用程序来说,这足够了,这些应用程序在这里和那里想要少量的Ajax。

它给那些认为jQuery.load和script标签无处不在的开发人员是最好的选择,因为切成薄片的面包刚好可以用来挂自己。

缺点

  • 违反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的过程,并且需要设置诸如数据绑定之类的内容以使表单显示错误。 这导致代码重复。

这是SPA框架(例如Ember和Angular)出现的地方,它们完成了客户端中的所有模板和渲染。

我该如何处理我可以在Plain Javascript / jQuery中处理的部分内容?

您可以创建其他格式,以供控制器响应。 例如,您可以注册"text/html-partial" MIME类型。

或创建其他路由,甚至使用查询参数(抖动)。

但是,由于与js.erb完全相同的原因,这并不理想-它导致API糟糕,因为您的控制器将变为进程而不是面向资源的。 您最终将创建荒谬的控制器操作,只是将html片段传递回客户端。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM