我正在开发一个应用程序,其中使用远程表单从许多不同的位置更新某个模型。我正在寻找一种模式来在更新这个模型后动态调用正确的JS回调。
使用普通表单可以通过在表单中传递重定向URL然后重定向到控制器中的此URL来解决。远程表单方面更难:我应该传递文件名吗?我应该传递一个任意字符串,然后在单个.js.erb文件中打开该字符串吗?还有其他建议吗?
这只是表明应该重新构建应用程序以防止从多个位置更新同一模型吗?
答案 0 :(得分:2)
不行它如果您可以从不同的位置调用相同的控制器动作。
您的选择:
1)优选地,该控制器动作可以给出相同的响应并且将适用于不同的位置,例如。它只是更新一个带有id的容器,该容器存在于所有这些位置。
2)您注意到重定向过去使事情变得简单,请考虑将以下内容添加到应用程序控制器中:
def js_redirect_to(path, flash_messages = {})
flash_messages.each { |type, message| flash[type] = message }
respond_to do |format|
format.js { render :js => "window.top.location='#{path}';" }
end
end
这是与普通redirect_to相同的签名,它只允许您从js请求重定向。请注意,如果您使用turbolinks,则js应为'Turbolinks.visit(url);'。
3)如果你真的无法像上面的选项一样处理它,你可以在表单中传递你提交的位置的JS命名空间,并且控制器为所有位置调用相同的方法,它只是一个不同命名空间例如:
假设一个位置来自宠物管理,然后是资产pet.js:
var pet = {
load = function() {
your page load js...
},
... more functions...
post_callback = function(html_segment1, html_segment2) {
this is where you handle the form callback for pets...
$('some_element').html(html_segment1);
$('another_element').html(html_segment2);
}
}
为应用的其他位置构建更多类似内容。像这样使用JS命名空间无论如何都是个好主意。然后您的表单提交参数:location => :宠物对控制器,响应:
... your JS code that all pages should execute...
html_segment1 = "<%= escape_javascript(render 'some_partial') %>";
html_segment2 = "<%= escape_javascript(render 'other_partial') %>";
<%= @location %>.post_callback(html_segment1, html_segment2);
4)使用小部件gem,最受欢迎的是apotomo或cells。
5)只需在控制器中使用一个案例来渲染不同的视图。
希望这有帮助,如果您需要澄清,请告诉我。