作为一个经验不足但快速学习的Rails开发人员,我想编写一个控制器后过滤器来检查AJAX请求,并在自定义标头中返回一些HTML,响应处理程序可以使用它来显示任何flash消息。
为了保持DRY的一致性和一致性,我想使用Rails生成的相同app / views / layouts / _messages.html.erb(.haml)来创建部分HTML。
在查看了几个帖子之后,我的解决方案是:
# adapted from http://stackoverflow.com/a/2729454/270511
def flash_to_headers
return unless request.xhr?
response.headers['X-flash'] = render_to_string partial: 'layouts/messages.html'
flash.discard # don't want the flash to appear when you reload page
end
这实际上会返回所需的标题,但也会throws an exception。
后续搜索显示几个帖子,其中受访者声称不支持从后过滤器调用render_to_string。
我想到的另一个解决方案是第二次从views / layouts / application.html.haml渲染layouts / navigation.html,但是在div中包含display = none。要使用相同的模板完成此操作,我将不得不向flash [:notice,:warn和:error]添加一些虚假的占位符消息,因为否则_messages.html.haml写入时不会在没有相关的情况下呈现部分消息。然后我可以使用占位符作为模板来克隆并填写后续AJAX请求返回的flash消息。
虽然这可能有用,但我觉得它很难看并且有难闻的气味。 (我对Rails缺乏经验,但没有进行软件开发!)由于我缺乏Rails经验(以及缺乏可用的导师),我可能错过了一些东西。如果是这样,如果有人可以指出一种更清洁的方式来实现我的目标,我将不胜感激。
如果没有,我会将此重新发布到Github上的rails问题列表中。我认为显示flash消息以指示从最终用户的AJAX请求的一些反馈是一个常见的用例Rails应该更好地支持它。
答案 0 :(得分:0)
我认为我的AJAX请求是API调用,因此我只在我的邮件头中发送最少的信息,并且只发送最相关的错误消息
application_controller.rb
return unless request.xhr?
if type = priority_flash # Method that returns most relevant message
response.headers['X-Message'] = flash[type]
response.headers['X-Message-Type'] = type.to_s
flash.discard # don't want the flash to appear when you reload page
end
呈现错误消息的工作应该属于javascript文件
some_js_file.js
// AJAX callbacks
$(document).ajaxComplete(function(e, request, opts) {
fireFlash(request.getResponseHeader('X-Message'), request.getResponseHeader('X-Message-Type'));
});
$(document).ajaxError(function(event, jqxhr, settings, thrownError){
fireFlash("AJAX request failed : " + jqxhr.status + " "+thrownError, "danger")
});
/* AJAX Flash messages */
function fireFlash(content, type){
if (content === null){
return
}
var alert_type;
switch(type){
case "alert":
case "danger":
case "fatal":
case "error":
alert_type= "danger"
break;
case "success":
case "notice":
alert_type= "success"
break;
case "warning":
alert_type= "warning"
default:
alert_type= "info"
}
$("#flashes").prepend($("<div/>")
.addClass("alert alert-dismissible alert-ajax alert-"+alert_type)
.html((decodeURIComponent(escape(content))))
.append('<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>')
)
document.location.href = "#top";
}