Rails 4:使用闪存重定向Turbolinks

时间:2015-08-19 16:53:15

标签: javascript ruby-on-rails ruby-on-rails-4 turbolinks

让我们说我有一个标准的控制器创建动作:

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."}

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

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

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

另外,如何才能显示Flash成功消息?

2 个答案:

答案 0 :(得分:3)

这不是您问题的直接答案。但我建议使用不引人注目的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' %>");
  • 这就是渲染:js将被渲染回浏览器,从而执行一个脚本,用新的flash消息替换你的flash容器(#flash或你使用的任何id)
  • 此外,请确保您拥有包含Flash HTML代码的部分视图文件app / layouts / _flash.html.erb。

更新

如果不使用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还没有支持部分加载,所以它总是加载整个主体。

答案 1 :(得分:2)

这就是我最终使用Turbolinks和materialize toasts来解决这个问题,以获得一个出色的Flash UX:

在我的控制器中:

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

在create.js.erb中:

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

在我的_flash.html.erb partial:

<% 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 %>