首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >升级到rails 5.2 -远程窗体现在刷新页面

升级到rails 5.2 -远程窗体现在刷新页面
EN

Stack Overflow用户
提问于 2021-03-08 17:18:13
回答 2查看 423关注 0票数 0

我正在尝试将Rails 5.1.7应用程序升级到5.2.0。网站上的一些表单被升级打破了。表单的模板如下所示:

代码语言:javascript
复制
<%= form_with model: record, url: client_field_value_path(@dataset, record), remote: true do |form| %>
  <%= the form contents %>
<% end %>

我认为表单中唯一相关的部分是它使用remote: true。我发现在Rails 5.2中,remote: true被更改为form_with助手的默认设置。我相信这是用不显眼的javascript实现的,但我对ujs的理解不是很好。

表单是在不重新加载页面的情况下提交的,页面中的状态更改由ajax侦听器处理。我们使用jquery -客户端代码包括行:

代码语言:javascript
复制
  $(this.form).trigger('submit');

它正在执行本地提交,而不是远程提交。这样页面就会刷新,JSON响应就会呈现出来。我发现针对rails-ujs的问题看起来是相关的,他们建议用

代码语言:javascript
复制
form = document.querySelector('form');
form.dispatchEvent(new Event('submit', {bubbles: true}));

或者,用rails-ujs,

代码语言:javascript
复制
form = document.querySelector('form');
Rails.fire(form, 'submit');

我已将rails-ujs添加到application.js文件中:

代码语言:javascript
复制
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
// ....
//= require jquery
//= require jquery_ujs
//= require rails-ujs
// ....

(jquery和jquery_ujs已经存在了)。我尝试了上述两种建议,但它们似乎都没有触发表单的提交。我真的被困住了!如果有更多的细节我可以提供,请问。我不太理解ujs的情况,所以我有点迷路了。

编辑:完整的保存调用--这是在单击“保存”按钮时触发的(但该按钮不是<input type=submit>,它只是一个样式的按钮)。

代码语言:javascript
复制
  save(event) {
    if( event ) {
      event.preventDefault();
      event.stopPropagation();
    }

    this.container.addClass('saving');

    // this.form.submit();
    Rails.fire(this.form[0], 'submit');


    this.container.find(".field-controls button").prop('disabled', true);
  }

更新:,我已经设法让它正常工作了。我非常感谢您能帮助我理解以下更改的来源,以及应用程序配置中是否出现了一些问题,这使得它变得比必要的更难。

  • 在表单中显式地将remote: true更改为local: false
    • 没有这一点,data-remote=true属性就不会在HTML中设置。

    • 只保留空白是不够的,尽管它应该是默认的。如果我不提供local: false,我就会进入控制台:

代码语言:javascript
复制
$('form[data-remote=true]').length
0
    • 根据这个答案,默认值由Rails.application.config.action_view.form_with_generates_remote_forms配置。这个值是控制台中我的nil。我找不到它被覆盖的任何地方。

  • 在我的JS资产中添加了rails-ujs并删除了jquery_ujs
    • 我需要包含rails-ujs,以便定义Rails (下一步需要)。

    • 当包含rails-ujs时,我收到了一个JS警告:应该删除jquery_ujs。我认为这是包括在jquery-rails宝石-我也安全地删除它吗?

  • this.form.submit()改为Rails.fire(this.form[0], 'submit')
    • $(form).submit()的任何变体都执行本地提交,而不是远程提交。

    • 在以前的版本中,jQuery提交是远程的,而不是本地的。

    • 我不知道这是在哪里记录的。上面链接的答案对此进行了解释--但这真的是RoR打算提交ajax表单的方式吗?我发现在这个意义上有一种“正确的方式”和“错误的方式”来提交表格,这是非常不直观的。

  • 更改了ajax:success处理程序的签名。
    • 同样,我也没有找到解释这种变化的地方,但我想这只是“rails-ujs是如何做到的”。我必须通过ajax处理程序从

代码语言:javascript
复制
  form.on('ajax:success', (event, response, status) => {
    $.each(response, (i, key) => {
      do_stuff();
    });
  });

代码语言:javascript
复制
  form.on('ajax:success', (event) => {
    const [response, _status, _xhr] = event.detail;
    $.each(response, (i, key) => {
      do_stuff();
    });
  });

同样,我想这是因为事件是由rails-ujs处理的,而不是由jquery处理的,但是.为什么?你怎么会知道?

EN

回答 2

Stack Overflow用户

发布于 2021-03-08 21:54:20

好吧,我想了几件事。

本地: false而不是remote: true

首先,form_with不再有remote选项了,它被称为本地:

代码语言:javascript
复制
<%= form_with model: record, url: client_field_value_path(@dataset, record), local: false do |form| %>
  <%= the form contents %>
<% end %>

而且,您应该能够跳过这一点,因为这是默认的。您可以通过删除它,然后检查指向此表单视图的路由的html标记来确认这一点,您应该可以在表单标记中看到data-remote="true"。这可能不是问题所在。

您的jQuery代码在哪里?

通常,ujs的工作方式是在视图目录中有一个名为create.js.erb的文件。当您提交表单时,该文件中的JS将运行,您将能够在该模板中使用erb标记向js添加动态内容。例如,您可以在这里使用render来呈现一个部分,并传入控制器中定义的实例变量。

当然,如果您已经单独设置了所有的javascript,并且它应该只在使用javascript时才能正常工作,那么它就不再是UJS。UJS代表不引人注目的javascript。这个想法是,javascript增强了功能,而不是取代它。这意味着,如果您的javascript由于某种原因没有加载,表单仍将提交并正常工作,而不需要使用javascript。这可能不是你的应用程序的情况,这很好,但知道提供一个更好的答案是有用的。

UJS模式的工作方式依赖于一些控制器代码。因此,控制器中有一个respond_to块,可以同时响应html请求和js请求。如果表单是远程的,那么它将在与控制器操作匹配的文件中运行javascript。例如,

代码语言:javascript
复制
def create 
  @record = Record.new(record_params)
  respond_to do |format|
    if @record.save
      format.html { redirect_to records_path }
      format.js {}
    else 
      format.html { render :new }
      format.js { render :error }
    end
  end
end
end
票数 1
EN

Stack Overflow用户

发布于 2021-03-09 20:41:20

我现在明白这个问题了!我以前很困惑。

答案

出于某种原因(我仍然不明白),

代码语言:javascript
复制
Rails.application.config.action_view.form_with_generates_remote_forms

升级后未设置。由于未设置data-remote="true"属性,所以jquery没有使用AJAX提交表单。在我的初始化中将这个配置变量设置为true解决了这个问题。

离题

想到rails-ujsjquery-ujs的替代品,我感到非常困惑。事实并非如此。他们的工作方式完全不同!jquery拦截通过jquery调用的事件,以便(例如)获取与AJAX一起提交的远程表单。通过创建自己的事件并使用Rails.fire调用它们,rails-ujs具有相同的功能效果。他们在一起打得不好!

我在添加rails-ujs之后遇到的所有困惑都源于这样一个事实:它们基本上是具有不同API的不同库。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66534265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档