0

我有一个带有 redirect_to 的按钮,它运行我的控制器操作,它为我的模型创建了一个新行。第一次,它正确创建并重定向。重定向后,我通过菜单转到上一页并重复相同的操作。单击该按钮后,它会重定向到正确的页面(它不应该...缓存?),然后显示我之前的 Flash 消息。所以它是重复的。我放入了一个调试器语句,以查看它在第二次运行时发生的位置——它实际上发生在我的按钮操作执行之前。运行其余代码后,它使用相应的(第二个)闪存正确重定向(但由于它过早地重定向,重定向到同一页面)。如何摆脱额外的初始 Flash 消息?

这是一张显示我的意思的图片:

在此处输入图像描述

如果您查看 URL 正下方的蓝色加载栏,则表明该页面尚未加载(我使用调试器语句将其停止,如下所示)。然而,重定向和闪存已经发生,这是不应该的,因为预期的重定向和闪存将在 turbolinks 完成页面加载后发生。

初始链接:

<%= link_to create_wager_from_favorite_wager_path(favorite_wager), data: { confirm: 'Create this wager?' } do %>
  Create Wager
<% end %>

控制器动作:

def create_wager_from
  debugger
  # on second run through, the redirect and flash happens before I reach this point
  @favorite_wager = FavoriteWager.find(params[:id])
  @anchor = params[:anchor]

  set_member_statuses()
  result_message = @favorite_wager.create_wager_from_favorite(current_user)

  respond_to do |format|
      format.html { redirect_to my_wagers_path(:game => @favorite_wager.game), notice: "Wager created successfully!" }
  end
end

在这一点上,它遵循标准路径,我 99% 确定其余代码无关紧要。

我尝试在加载按钮操作的页面时检查 flash 参数,但它是空的。所以我不确定是什么导致了这个问题。任何见解表示赞赏。

更新:更改为 flash.now[:notice] 会使重复项停止,但 Flash 仅在第一次单击按钮时显示。然后它不会在任何时候出现。刷新页面将允许错误重复。

4

2 回答 2

0

在阅读了 Turbolinks 之后,我确定这个问题的原因是 turbolinks 中称为“页面预览”的自然内置功能。这是它将在服务器响应到达之前将先前缓存的页面显示为一种“预览”的地方,这给人一种页面已经加载的错觉。

但是,在我的案例中,缓存的重定向页面在提供服务的那一刻就被缓存了,这意味着 Flash 消息也被捕获到了该缓存中。所以在我第二次点击创建按钮时,它会用 flash 加载缓存的页面,然后重新重定向为真实的并再次 flash(就像它应该做的那样)。

所以这里的解决方案是要么 a. 禁用所有页面预览或 b。禁用该特定链接的 turbolinks。我选择了b。因为它不会影响我的程序的其余部分,代价是蓝色加载动作不再存在。这是下面的解决方案(非常简单):

前:

<%= link_to create_wager_from_favorite_wager_path(fw, :anchor => anchor), data: { confirm: 'Create this wager?' }, class: "red-btn create-favorite-wager-btn" do %>
  Create Wager
<% end %>

后:

<%= link_to create_wager_from_favorite_wager_path(fw, :anchor => anchor), data: { confirm: 'Create this wager?' }, "data-turbolinks": "false", class: "red-btn create-favorite-wager-btn" do %>
  Create Wager
<% end %>

于 2020-05-17T10:24:18.500 回答
0

要防止元素在缓存页面(包括预览)中可见,请删除turbolinks:before-cache. 例如,您可以在主应用程序 JavaScript 文件中包含类似这样的内容:

addEventListener('turbolinks:before-cache', () => {
  document.querySelectorAll('.flash').forEach(element => element.remove())
})

有关此结帐的更多信息https://github.com/turbolinks/turbolinks#understanding-caching

于 2020-05-18T20:13:24.770 回答