【问题标题】:Rails 3, find current view while in the layoutRails 3,在布局中查找当前视图
【发布时间】:2011-06-25 19:31:13
【问题描述】:

我有一个场景,当我在布局文件中时,我想拥有将要呈现的视图的名称。我可以找到解决方案来查找哪个布局将从视图中包装当前视图,但不能反过来。如何找到正在渲染的视图?

【问题讨论】:

    标签: ruby-on-rails templates layout


    【解决方案1】:

    我喜欢以下方法,因为您可以在很多情况下大大减少代码大小。将此包含在您的 application_controller.rb 中:

      before_filter :instantiate_controller_and_action_names
      caches_action :instantiate_controller_and_action_names
    
      def instantiate_controller_and_action_names
        @current_action = action_name
        @current_controller = controller_name
      end
    

    然后,如果您的视图对应于一个操作,您只需:

    dosomething if @current_action == 'new'
    

    【讨论】:

    • 这并不能完全解决我的问题。我需要视图的名称,它并不总是与被调用的操作相同。
    • 然后添加一个空白动作,例如 def 不管结束。
    【解决方案2】:

    在 Rails 3.0.3 中,我可以使用 controller_name 和 action_name 查看控制器和操作的名称。但这些都没有公开记录(至少是动作名称),所以我不会长期依赖它。

    猴子补丁模板渲染可能会更好。在初始化器中:

    module ActionView::Rendering 
      alias_method :_render_template_original, :_render_template
      def _render_template(template, layout = nil, options = {}) 
        @last_template = template
        _render_template_original(template, layout, options)
      end
    end
    

    然后在你的布局中使用@last_template。

    【讨论】:

    • 这对我很有用。为了添加更多细节,在 Rails 3 中,我将其添加到新文件 config/initializers/custom_renderer.rb 中,然后在视图中我能够访问 @last_template.variable_name 以获取例如“new”跨度>
    • ActionView::Rendering 在 Rails 3.1 中不再存在。
    【解决方案3】:

    以下解决方案适用于 Rails 3.1。将此代码放在初始化程序中。 (rails 3.0.3 的答案在 Rails 3.1 中不再起作用)

    这会为每个控制器启用一个@active_template 变量。这是一个 ActionViewTemplate 类的实例。

    方法 active_template_virtual_path 方法以“控制器/动作”形式将模板作为名称返回

    
        class ActionController::Base
          attr_accessor :active_template
    
          def active_template_virtual_path
            self.active_template.virtual_path if self.active_template
          end
        end
    
        class ActionView::TemplateRenderer 
    
          alias_method :_render_template_original, :render_template
    
          def render_template(template, layout_name = nil, locals = {})
    
            @view.controller.active_template = template if @view.controller
            result = _render_template_original( template, layout_name, locals)
            @view.controller.active_template = nil if @view.controller
            return result
    
          end
        end
    

    【讨论】:

    • 这适用于我的 Rails 3.1.3。尽管我稍微缩短了解决方案:@view.assign(:active_template => template) 位于render_template 中,但您可以删除一堆额外的代码并以@active_template 的身份访问视图中的模板。
    • 我发现这给 'exception_notification' gem 带来了一些麻烦。为了解决这个问题,我做了these changes
    • 我遇到了嵌套布局问题 (guides.rubyonrails.org/…)。 active_template 设置为我最顶层的布局,而不是来自控制器的视图。为了解决这个问题,我在 assginment 上添加了一个额外的条件:@view.controller.active_template = template if @view.controller && @view.controller.active_template.nil?
    猜你喜欢
    • 2014-02-24
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多