如何将变量传递给布局?
我有两个版本的应用程序布局,它们只有几行不同。 请考虑以下示例:
!!! %html %head # a lot of code here %body # some more code here - if defined? flag and flag == true # variant 1 - else # variant 2
问题是,如何将此标志传递给布局?
class ApplicationController {:flag => true} #won't work :( # ... end
控制器实例变量? 这是获取模板信息的常用方法。
在这些情况下,我通常更喜欢使用辅助方法而不是实例变量。 以下是如何完成的示例:
class ApplicationController < ActionController::Base layout 'layout' helper_method :flag ... protected def flag true end end
如果你有一个控制器,其中flag不应该是true,那么你只需覆盖该方法:
class PostsController < ApplicationController ... private def flag false # or perhaps do some conditional end end
这样,您可以确保标记帮助程序始终在视图中可用,因此您不必执行if defined?
或者任何东西,并且在没有使用布局的情况下,在任何before_filter
中都没有分配实例变量。
它还有助于在视图中保留尽可能少的实例变量。
好的,所以我自己找到了解决方案:
class ApplicationController < ActionController::Base layout 'layout' before_filter :set_constants def set_constants @flag = true end end
模板应该是:
!!! %html %head # a lot of code here %body # some more code here - if @flag # variant 1 - else # variant 2
另外还有两个选择 ,OP实际上是这样做的:
#1
在你的布局中:
- if flag ||= false # variant 1 - else # variant 2
在您的应用程序控制器中(这是技巧):
layout 'application' # or whatever
在任何类型的控制器:
render :locals => { :flag => true }
我的猜测是,布局处理后来发生了“动态”(不是真正的) layout
定义,并为local_assigns
内的所有键生成必要的方法。 因此,实例变量可能是一种性能解决方案。 有什么想法吗? 请发表评论。
#2
您可以使用local_assigns
变量,如:
- if local_assigns[:flag] ||= false # variant 1 - else # variant 2
然后在你的任何一个控制器中:
render :locals => { :flag => true }
为了有条件地选择布局,这个http://snippets.dzone.com/posts/show/236怎么样?