首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解rails presenter中的收益

了解rails presenter中的收益
EN

Stack Overflow用户
提问于 2013-09-26 14:09:14
回答 3查看 371关注 0票数 1

在我正在读的“Rails View”一书中,有一些关于presenters的代码

代码语言:javascript
复制
app/helpers/designers_helper.rb

module DesignerHelper
  def designer_status_for(designer = @designer)
    presenter = DesignerStatus.new(designer)
    if block_given?
      yield presenter
    else
      presenter 
    end
  end
end

然后在show.html.erb中

代码语言:javascript
复制
<% designer_status_for do |status| %>
   some html using <%= status %> variable

<% end %>

我很难理解代码块是如何获得变量状态的,为什么我们需要在helper函数中使用'if‘语句,为什么不直接返回presenter变量?

EN

回答 3

Stack Overflow用户

发布于 2013-09-26 14:30:18

让我们从视图开始

代码语言:javascript
复制
<% designer_status_for do |status| %>
   "some html using <%= status %> variable"    
<% end %>

这将使用block代码调用方法designer_status_for,如下所示

代码语言:javascript
复制
designer_status_for {|status| "some html using <%= status %> variable" }

在该方法中,

代码语言:javascript
复制
presenter = DesignerStatus.new(designer)
#=>since no `designer` is given it takes the default value of `@designer` 
#  and finds the related presenter

if block_given?
#=> is true since a block is given 

yield presenter
#=> here the method "yields" to the block 
#   i.e. passes the presenter as a variable to the block and executes it. 
#   For e.g. array.map{|x| x+1} works the same way
#   `map` iterates over the array and yields each element to the given block.

{|status|   "some html using <%= status %> variable"}
#=> status is the variable received from method which is presenter
#   This block returns the html to the method that called it

end 
#=>the last statement was yield which was equal to the html returned from block
#  returns the html received from the block 

该方法中的if语句将返回代码块的结果,否则它将返回presenter。这允许干代码,我们需要在代码块中的一堆地方使用presenter变量。

票数 1
EN

Stack Overflow用户

发布于 2013-09-26 14:55:14

好的,让我们一步一步来。

首先,您定义了一个帮助器方法,它将@designer指定为默认值。这就是为什么你可以在视图中没有任何参数的情况下调用它的原因:

代码语言:javascript
复制
<% designer_status_for do |status| %>
  # more code

然后,DesignerStatus是实际的presenter,它是一个与Designer不同的类,它创建了一个全新的对象,但它在某种程度上是基于@designer对象的。因此,presenterDesignerStatus类型的新对象

正如你可能猜到的那样,block_given?会检查这个对象是否应该传递给一个块,或者它是否应该像一个普通对象一样工作。这很可能是你难以理解的棘手的部分。所以让我以另一种方式来解释。你可以这样叫它

代码语言:javascript
复制
designer_status_for.some_presenter_method

在你看来,这是可行的。它是有效的,因为没有给出任何块,并且返回一个designer对象(换句话说,触发了else部件),您可以直接对该对象调用some_presenter_method。因此,您可以在整个视图中使用所有这些,这样就没问题了。

然而,还有一个更好的选择,那就是将这个对象yield成一个块。yield选项使此代码片段成为可能

代码语言:javascript
复制
<% designer_status_for do |status| %>
  status.some_presenter_method
<% end %>

一开始就有可能。这基本上意味着“将presenter对象赋给一个名为status的变量,并使该变量可用于该块。

所以,如果你现在很难理解yield,也不用太担心。只需调用designer_status_for本身的任何方法即可。使用块而不是对象本身的好处是,您的代码变得不那么脆弱,但这是另一个主题。

票数 1
EN

Stack Overflow用户

发布于 2013-09-26 14:38:52

在发布了这个问题后,我尝试重新阅读代码,并在irb中尝试了一些示例,以下是回答我问题的结果。

在Ruby中,任何方法都可以使用一段代码。例如。

代码语言:javascript
复制
def method_can_take_block?
  answer = 'yes it can take block of code'
end

method_can_take_block? { puts 'this code is not executed but gets passed to method' }

要执行我的代码块,需要在方法内部生成它。只需在方法内部调用yield,就可以生成代码块。通过显式调用yield,我们可以控制代码块的执行行。

代码语言:javascript
复制
def method_can_take_block?
  answer = 'yes it can take block of code'
  yield
end

method_can_take_block? { puts 'this code gets executed after the variable 'answer' gets assigned with some value.' }

然而,我们在这里没有使用任何变量'answer‘。传递的代码块不能访问函数内部定义的变量。因此,为了给块一些访问方法内部定义的变量的权限,我们需要让块接受一些参数。请注意下面代码块中|my_answer|的用法。

代码语言:javascript
复制
   method_can_take_block? { |my_answer| 100.times { puts answer } }

现在我们已经在代码块中添加了一个参数,我们需要在调用代码块时传递这个参数。因此,这是通过使用附加参数调用yield来完成的。

代码语言:javascript
复制
def method_can_take_block?
  answer = 'yes it can take block of code'
  yield answer
end

yield answer将answer变量传递给传递给该方法的代码块。在本例中,answer作为my_answer变量在块内传递,然后打印100次。

有了这样的理解,我对问题的回答

  1. 代码块如何获得变量状态,赋值ans:通过yield presenter行。这里,呈现器变量被传递给接收名称为status.
  2. why的参数的块。我们需要在辅助函数中使用'if‘语句吗?为什么不直接返回presenter变量呢?我们可以很好地避免将整个erb作为块传递给方法,但是我们需要在show.html.erb:

的顶部有一个如下所示的代码

状态,然后开始使用变量<% status = designer_status_for(@designer) %>。我认为使用block是一个美学问题,这样我们就可以避免使用赋值。方法中的if语句就是要使用这种语法,而不是使用块。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19020601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档