2017-08-08 33 views
0

在ajax请求之后,向用户显示消息的最佳方式(即最可维护,干燥)是什么?如何为ajax请求编写DRY Flash消息?

显然,为单个JS控制器操作实现此目的的最简单方法是简单地使用关联的JS部分。例如,

#create.js 
$('.flash-container').html('<p>SUCCESS!</p>'); 

但是,如果应用程序中包含大量ajaxed动作,这很快变得难以维护,需要许多谐音进行更新,如果需要作出改变。

我目前使用的方法如下。但是这总是显得非常脆弱和'哈克' - 我必须忽视Rails约定?

这是第一次在页面上触发ajax请求时返回That page doesn't exist!。所有后续请求都会返回预期的结果,直到页面重新加载。到底是怎么回事?

#my_controller.rb 
def create 
    if @object.save 
    format.js { flash[:notice] = t('.notice') } 
    else 
    format.js { flash[:error] = t('.error') } 
    end 
end 
# application_controller.rb 
after_action :flash_to_headers 
def flash_to_headers 
    return unless request.xhr? 
    response.headers['X-Message'] = flash_message 
    response.headers["X-Message-Type"] = flash_type.to_s 
    flash.discard 
end 
def flash_message 
    [:alert, :error, :notice, :success].each do |type| 
    return flash[type] unless flash[type].blank? 
    end 
    return nil 
end 

def flash_type 
    [:alert, :error, :notice, :success].each do |type| 
    return type unless flash[type].blank? 
    end 
    return :empty 
end 

#flash.js.coffee 

$(document).ajaxComplete (event, request) -> 

    msg = request.getResponseHeader("X-Message") 
    type = request.getResponseHeader("X-Message-Type") 

    if msg 
    alert(msg) 

回答

0

为什么不改变你的js部分的js.erb部分和嵌入你希望它被解析成标准的JS,而不是通过头发送之前发送的消息?

以同样的方式

你可以有.html.erb文件,你也可以有.js.erb文件:

# create.js.erb 
<% if flash[:notice] %> 
$('.flash-container').html('<p><%= flash[:notice] %></p>'); 
<% end %> 

在保持其维护和干燥而言,这只是下到代码的设计,创建一个共享js.erb局部您呈现其他.js.erb parials内:

# some_controller.rb 
helper_method :handle_ajax_messages 

# create.js.erb 
$('.flash-container').html('<p><%= handle_ajax_messages %></p>'); 

#shared/_ajax_messages.js.erb 
<% if flash[:notice] %> 
$('.flash-container').html('<p><%= flash[:notice] %></p>'); 
<% end %> 
<% if flash[:error] %> 
$('.flash-container').html('<p><%= flash[:error] %></p>'); 
<% end %> 

# create.js.erb 
<%= render(partial: 'ajax_messages') %> 

在顶级控制器创建共享是helper_method

你可以提取一个ServiceObject处理程序,或者如果你的工厂是DDD来创建自定义的NoticeObjects或值对象和#to_html#to_js#to_json等方法来保持对所有类型的请求DRY。如果你打破了一些所谓的“Rails约定”,有很多其他选项和方法可以保持代码的干爽和可维护性。

+0

感谢这个广泛的答案。你的第一个建议仍然需要'ajax_messages'手动插入每个JS部分。但是,如果我希望“ajaxified消息”成为当前存在的或将来可能添加的任何操作的默认值,那么标题是否是最佳方式?如果是这样,为什么我会得到这个奇怪的'该页面不存在!'第一次发送请求? –

+0

DDD可能是我在找的东西。你能否提出任何基本的rails示例/教程,以帮助我更好地了解如何实现这种方法? –

+0

确实第一部分只是解释一下,你可以使用嵌入式ruby和js文件,然后打开它们到你的整个ruby代码库,允许你以任何你想要的方式干掉它。林不知道为什么你得到的页面不存在的错误,并在头部方面,虽然它可能是一种可行的方法,我不会亲自使用它。 DDD,但我强烈建议,因为它允许您创建DRY可重复使用的代码,以便在几乎任何情况下都可以很容易地进行调整和重用,正如我在上面提到的那样,我会创建可翻译的值对象。链接: –