Rails 6:带有远程的表单:true 和 Turbolinks 在重定向后不显示 Flash

mat*_*iss 3 ruby-on-rails ujs simple-form turbolinks ruby-on-rails-6

<%= simple_form_for @offer, remote: true %>启用了 Turbolinks。我正在尝试在我的update操作中使用以下内容重定向并显示成功闪烁:

respond_to do |format|
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    format.html { redirect_to seller_offers_path }
    format.js
  else
    format.html { render :edit }
  end
end
Run Code Online (Sandbox Code Playgroud)

我的update.js.erb代码与重定向或闪存无关:

$(".ibox-content.actions").removeClass('sk-loading');
$('.sk-spinner').css("display", "none");
Run Code Online (Sandbox Code Playgroud)

在 application.html.erb 中,我可以用这个渲染 flash:

<div class="row">
  <% flash.each do |message_type, message| %>
     <%= content_tag(:div, content_tag(:strong, message), id: "flash_message",
                   class: "text-bold alert alert-#{message_type}") %>
  <% end %>
</div>
Run Code Online (Sandbox Code Playgroud)

目前我的表单已保存,但没有重定向。

当我添加Turbolinks.visit(<%= seller_offers_path %>)update.js.erb形式保存,重定向做,但没有闪光灯。

有没有办法让我可以在带有 Turbolinks 的重定向页面上显示 Flash remote: true,拜托?到目前为止,我已经尝试过这个建议,但是它仅适用于在同一页面上显示 Flash - 它不适用于redirect_to.

更新

这确实重定向,但没有闪光:

respond_to do |format|
  if @offer.update(offer_params)
    format.js { redirect_to seller_offers_path, success: "#{@offer.name} #{t(:updated)}" }
  else
    format.html { render :edit }
  end
end
Run Code Online (Sandbox Code Playgroud)

更新 2

目前我想实现像 Turbolinks.visit(url, { keep: 'flash' });在文档中提到,但似乎并没有与Turbolinks 5.2合作

更新 3

我已经删除了,update.js.erb并且在我的控制器中我有

def update
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    redirect_to seller_offers_path
  else
    render :edit
  end
end
Run Code Online (Sandbox Code Playgroud)

重定向按预期完成,但仍然没有显示 Flash index。我可以在update行动结束时打印我的闪光:

#<ActionDispatch::Flash::FlashHash:0x00007f180d2a1c60 @discard=#<Set: {}>, @flashes={"success"=>"My offer updated!"}, @now=nil>

但是在index动作结束时(我重定向到的地方)它是空的:

#<ActionDispatch::Flash::FlashHash:0x00007f180eb3b780 @discard=#<Set: {}>, @flashes={}, @now=nil>

看起来我的闪存没有为下一个请求保留。是因为 Turbolinks 还是其他原因?我很乐意提供任何提示。

Dom*_*tie 6

远程表单提交后重定向

当您使用通过 JS 提交的表单(例如remote: true或默认form_with)时,Rails 将查找并呈现常规js响应(在本例中offers/update.js.erb)并忽略任何其他响应,例如html重定向。

您的原始文件update.js.erb不包含任何代码来执行对重定向位置的访问,因此它只删除了类名并隐藏了微调器。

正如您所发现的,js响应需要将 Turbolinksvisit发送到重定向位置。在提交表单后清除 Turbolinks 缓存也是一个好主意,因此您update.js.erb可能看起来像:

$(".ibox-content.actions").removeClass('sk-loading');
$('.sk-spinner').css("display", "none");
Turbolinks.clearCache();
Turbolinks.visit(<%= seller_offers_path %>);
Run Code Online (Sandbox Code Playgroud)

如果您安装了 turbolinks-rails gem,并且不需要像上面的前两行那样运行任何自定义 JS,那么在您的控制器中您可以简单地执行以下操作:

def update
  if @offer.update(offer_params)
    flash[:success] = "#{@offer.name} #{t(:updated)}"
    redirect_to seller_offers_path
  else
    render :edit # see note below*
  end
Run Code Online (Sandbox Code Playgroud)

你不需要update.js.erb; turbolinks-rails 将自动清除缓存并访问重定向路径。这很好,因为它使您的控制器代码保持整洁(不需要respond_to),并且适用于 HTML 和 JS 请求。

* 值得注意的是,来自 JS 请求的错误响应仍然需要手动处理。为此,您可能会发现此评论很有用:https : //github.com/turbolinks/turbolinks/issues/85#issuecomment-338784510

缺少闪光灯

我认为你的 flash 没有显示在你更新的代码中的原因是因为你使用了在redirect_to, which only supportsnotice andalert`中设置 flash 消息的速记风格:

redirect_to seller_offers_path, notice: '…' # sets flash[:notice]
redirect_to seller_offers_path, alert: '…' # sets flash[:slert]
redirect_to seller_offers_path, success: '…' # doesn't work
Run Code Online (Sandbox Code Playgroud)

如果您想使用自己的闪光键,则需要明确设置闪光:

flash[:success] = "#{@offer.name} #{t(:updated)}"
Run Code Online (Sandbox Code Playgroud)

我还应该补充一点keep,Turbolinks 5 不支持Turbolinks选项。我认为这是 Turbolinks 2 或 3 中的一个功能。Turbolinks README是最新文档的地方。

我希望有帮助:)

  • 我发现了我的问题 - 与其他一些 JS 和“lib”中的一个模块存在冲突。我删除了不必要的文件,现在我的闪光灯工作正常了。 (2认同)