我有两个版本的应用程序布局,它们只有几行不同。请考虑以下示例:
!!!
%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 < ActionController::Base
layout 'layout', :locals => {:flag => true} #won't work :(
# ...
end
答案 0 :(得分:16)
在这些情况下,我通常更喜欢使用辅助方法而不是实例变量。以下是如何完成的示例:
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
中分配。
它还有助于在视图中保留尽可能少的实例变量。
答案 1 :(得分:13)
好的,所以我自己找到了解决方案:
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
答案 2 :(得分:8)
控制器实例变量?这是获取模板信息的常用方法。
答案 3 :(得分:8)
还有另外两个选项,OP实际上是什么问题:
:
- if flag ||= false
# variant 1
- else
# variant 2
应用程序控制器中的(这是技巧):
layout 'application' # or whatever
在任何类型的控制器中:
render :locals => { :flag => true }
我的猜测是,布局处理后来发生了“动态”(不是真正的)layout
定义,并为local_assigns
内的所有键生成了必要的方法。因此,实例变量可能是一种性能解决方案。有什么想法吗?请发表评论。
您可以使用local_assigns
变量,如:
- if local_assigns[:flag] ||= false
# variant 1
- else
# variant 2
然后在你的任何一个控制器中:
render :locals => { :flag => true }
答案 4 :(得分:-1)
为了有条件地选择布局,这个http://snippets.dzone.com/posts/show/236怎么样?