Rails 4: Turbolinks 使用 flash 重定向

Rails 4: Turbolinks redirect with flash

假设我有一个标准控制器创建操作:

def create
  @object = Object.new(object_params)
  if @object.save
    redirect_to @object, flash: {success: "Created object successfully."}
  else
    render :new
  end
end

现在,如果我将重定向更改为使用 turbolinks:

redirect_to @object, turbolinks: true, flash: {success: "Created object successfully."}

服务器 returns 一个 text/javascript 响应,我的浏览器将其显示为白页,上面只有这行文本:

Turbolinks.visit('http:/localhost:3000/objects/1');

如何让我的浏览器实际执行该代码而不是将其显示为文本?

另外,如何让闪现成功消息出现?

这不是对您问题的直接回答。但我建议为此使用不显眼的 JS。您需要先在表单中添加 remote: true

def create
  @object = Object.new(object_params)
  if @object.save
    flash.now.success = 'Created object successfully.'
  else
    flash.now.alert = @object.errors.full_messages.to_sentence
  end
  render :js
end

创建一个仅包含以下内容的文件create.js.erb:

$('#flash').replaceWith("<%= j render partial: 'layouts/flash' %>");
  • 这就是 render :js 将呈现回浏览器的内容,从而执行一个脚本,用新的 flash 消息替换您的 flash 容器(#flash 或您使用的任何 id)
  • 此外,请确保您有一个局部视图文件 app/layouts/_flash。html.erb 其中包含您的 Flash HTML 代码。

更新:

如果不使用 Unobtrusive JS。您可以像下面这样渲染部分文件:

def create
  @object = Object.new(object_params)
  if @object.save
    flash.now.success = 'Created object successfully.'
  else
    flash.now.alert = @object.errors.full_messages.to_sentence
  end
  render partial: 'layouts/flash'
end

然后在您的 HTML 中嵌入如下内容:

$('#myForm').ajaxForm({
    url : '<%= url_for objects_path %>',
    type: 'post',
    dataType : 'json',
    success : function (response) {
        $('#flash').replaceWith(response);
    }
});

P.S。您可能还对 Wiselinks 感兴趣,它实际上已经这样做了(部分视图加载;您指定要替换的目标容器)。因为目前 turbolinks 还不支持部分加载,它总是加载整个 body。

这就是我最终使用 Turbolinks 和 materialize toasts 解决此问题以获得出色的闪存 UX 的方式:

在我的控制器中:

format.js {
  flash[:toast] = 'Created record successfully.'
  render :create
}

在create.js.erb中:

Turbolinks.visit("<%= success_path %>");

在我的 _flash.html.erb 部分:

<% flash.each do |type, message| %>
  <% if type == "toast" %>
    <script id="toast">
      $(function() {
        Materialize.toast('<%= message %>', 3000);
      });
    </script>
  <% elsif type == "success" %>
    ...
  <% elsif type == "alert" %>
    ... 
  <% end %>
<% end %>