1

@variable如何从控制器的视图中调用控制器操作中定义的实例变量?

喜欢

class UsersControllers
  def index
     @whythiscolavery=User.all
  end
end

现在在 /views/users/index.html.haml 为什么@whythiscolavery 在控制器操作中定义的视图中可以直接访问变量?

这个查询让我在一次重要的采访中失败了。

@whythiscolavery.each do   
     user.name
 end
4

6 回答 6

4

引用 Rails 3 中的 Obie Fernandez 的话:

Rails 实现控制器到视图数据切换的方式是通过实例变量。通常,控制器操作会初始化一个或多个实例变量。然后视图可以使用这些实例变量。

在选择实例变量以在控制器和视图之间共享数据时存在一些讽刺意味(对于新手来说可能会感到困惑)。实例变量存在的主要原因是对象(无论是 Controller 对象、String 对象等)可以保留它们不与其他对象共享的数据。当你的控制器动作被执行时,一切都发生在控制器对象的上下文中——例如,DemoController 或 EventController 的一个实例。上下文包括代码中的每个实例变量都属于控制器实例的事实。

渲染视图模板时,上下文是不同对象的上下文,即 ActionView::Base 的实例。该实例有自己的实例变量,并且无法访问控制器对象的变量。

因此,从表面上看,实例变量对于两个对象共享数据的方式来说是最糟糕的选择。然而,有可能让它发生——或者让它看起来发生。Rails 所做的是遍历控制器对象的变量,并为每个变量创建一个视图对象的实例变量,具有相同的名称并包含相同的数据。

对于框架来说,这是一种劳动密集型的工作:就像手动复制购物清单一样。但最终的结果是,对于程序员来说,事情变得更容易了。如果您是 Ruby 纯粹主义者,您可能会因为实例变量用于连接对象而不是分离对象而感到畏缩。另一方面,作为一个 Ruby 纯粹主义者还应该理解这样一个事实,即您可以在 Ruby 中做很多不同的事情——比如在循环中复制实例变量。所以没有什么真正不像Ruby的。从程序员的角度来看,它确实在控制器和它正在呈现的模板之间提供了无缝连接。

于 2013-07-30T11:05:55.377 回答
2

视图基本上是控制器的方法,因此它们可以像普通的普通旧 ruby​​ 类一样访问实例变量。如果你有课

class Donut
  def show
    @delicious = "very very delicious"
  end

  private
  def render_show
    "donuts are #{@delicious}"
  end
end

Donut.new.show

Erb(和 haml,以及 js 和所有其他渲染)以相同的方式处理。

于 2012-04-05T21:09:27.113 回答
1

控制器中的方法是公共操作(除非它们受到保护)。在该操作中分配的实例变量在该视图中可用。

于 2012-04-06T01:09:47.090 回答
1

因为在Ruby On Rails MVC 架构“约定优于配置”中,实例变量跨越模型/视图/控制器和助手。

于 2012-04-05T21:29:01.037 回答
0

用于此的 haml 语法为:

-@whythiscolavery.each do |user|
  = user.name

erb 语法是

<%= @whythiscolavery.each do |user| %>
  <%= user.name %>
<% end %>
于 2012-04-05T19:57:37.817 回答
0

如果您询问如何从视图访问变量,niiru 的答案很好,但 erb 语法示例中的额外“=”符号除外。它应该是:

<% @whythiscolavery.each do |user| %>
  <%= user.name %>
<% end %>

如果您问为什么该变量可能在视图中可用,那是因为控制器使它们对视图可用(它们被复制到视图中)。这个设计缺陷(保持状态)促使 gem 的 decent_exposure 的创建:https ://github.com/voxdolo/decent_exposure

于 2012-04-05T20:50:30.190 回答