Rails:捕获方法 [英] Rails: capture method
问题描述
以下代码来自 Ryan Bates 的 RailsCasts,其中他把博客的首页变成了日历,这样文章就会在几天内显示为链接.以下帮助器模块创建日历.我对这段代码有两个疑问
在
day_cell
方法中,他使用了一种叫做capture
的方法.我在上面找到了一些文档,但我仍然无法弄清楚捕获在这种情况下是如何工作的.另外,作为要捕获的参数传递的&callback
是什么?它会与传递给 Struct.new 的:callback
相同吗?如果是这样,它如何进入捕获状态?传递给 Struct 的 :callback 是什么?def day_cell(day)content_tag :td, view.capture(day, &callback), class: day_classes(day)结尾
源代码
module CalendarHelperdef 日历(日期 = Date.today, &block)绑定.撬Calendar.new(self, date, block).table结尾类日历<结构.new(:view,:date,:callback)HEADER = %w[周日周一周二周三周四周五周六]START_DAY = :星期日委托 :content_tag, to: :view定义表content_tag :表,类:日历"做标题 + week_rows结尾结尾定义头content_tag :tr 做HEADER.map { |天|content_tag :th, day }.join.html_safe结尾结尾def week_rows周.map 做 |周|content_tag :tr 做周.map { |天|day_cell(day) }.join.html_safe结尾end.join.html_safe结尾def day_cell(day)content_tag :td, view.capture(day, &callback), class: day_classes(day)结尾def day_classes(day)班级 = []类<<今天"如果 day == Date.today类<<"notmonth" 如果 day.month != date.month类.空??无:classes.join(" ")结尾定义周第一个 = date.beginning_of_month.beginning_of_week(START_DAY)last = date.end_of_month.end_of_week(START_DAY)(first..last).to_a.in_groups_of(7)结尾结尾结尾
我已经做了我的研究,我终于解开了谜团.
所以,有几件事要开始;像往常一样,文档不是很清楚,capture(*args) 方法应该将一块模板抓取到一个变量中,但它没有深入解释您可以将变量传递给抓取的模板,当然是以块
的形式出现的源代码来自 Ryan Bate 的日历截屏:
<h2 id="月"><%= link_to "<", 日期:@date.prev_month %><%= @date.strftime("%B %Y") %><%= link_to ">", 日期:@date.next_month %><%= 日历 @date 做 |date|%><%=日期.天%><% if @articles_by_date[date] %><ul><% @articles_by_date[date].each do |article|%><li><%=link_to article.name, article%></li><%结束%><%结束%><%结束%>
在上面的代码中,块将完全是这部分:
做 |日期|%><%=日期.天%><% if @articles_by_date[date] %><ul><% @articles_by_date[date].each do |article|%><li><%=link_to article.name, article%></li><%结束%><%结束%><%结束%>
所以,当他打这个电话时:
content_tag :td, view.capture(day, &callback), class: day_classes(day)
特别是:
view.capture(day, &callback)
这里发生的事情是他将day 参数作为|date| 参数(在块中)传递给块上面.
这里需要理解的是,在问题的背景下(制作 30 天日历);每月的每一天都与模板块(&回调)一起传递给捕获方法,这样做……结果是为给定月份的每一天呈现上面的块.最后一步当然是.. 将渲染的内容(每天)作为 content_tag :td
的内容最后一点;Ryan 在 view 变量上调用捕获方法,文档中也没有说明,但他在 ScreenCast 中提到他需要这个视图作为访问视图的代理",当然,视图是唯一可以访问 ViewHelper 方法的视图.
所以,总而言之,它是非常漂亮的代码,但只有当你理解它的作用时它才会漂亮,所以,我同意乍一看非常令人困惑.
希望这有帮助,这是我能想到的最好的解释.:)
The following code is from a Ryan Bates' RailsCasts in which he turns the front page of a blog into a calendar, so that articles show up as links on days. The following helper module creates the Calendar. I have two questions about this code
In the
day_cell
method, he uses a method calledcapture
. I found some docs on it but I still can't figure out how capture is working in this context. Also, what is the&callback
that's passed as an argument to capture? Would it be the same:callback
that's passed to Struct.new? If so, how does it get into capture? What is the :callback that's passed to Struct?def day_cell(day) content_tag :td, view.capture(day, &callback), class: day_classes(day) end
source code
module CalendarHelper
def calendar(date = Date.today, &block)
binding.pry
Calendar.new(self, date, block).table
end
class Calendar < Struct.new(:view, :date, :callback)
HEADER = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
START_DAY = :sunday
delegate :content_tag, to: :view
def table
content_tag :table, class: "calendar" do
header + week_rows
end
end
def header
content_tag :tr do
HEADER.map { |day| content_tag :th, day }.join.html_safe
end
end
def week_rows
weeks.map do |week|
content_tag :tr do
week.map { |day| day_cell(day) }.join.html_safe
end
end.join.html_safe
end
def day_cell(day)
content_tag :td, view.capture(day, &callback), class: day_classes(day)
end
def day_classes(day)
classes = []
classes << "today" if day == Date.today
classes << "notmonth" if day.month != date.month
classes.empty? ? nil : classes.join(" ")
end
def weeks
first = date.beginning_of_month.beginning_of_week(START_DAY)
last = date.end_of_month.end_of_week(START_DAY)
(first..last).to_a.in_groups_of(7)
end
end
end
I have done my research, and I've finally unraveled the mystery.
So, a couple of things to start with; as usual the documentation isn't very clear, the capture(*args) method is supposed to grab a piece of template into a variable, but it doesn't dig deeper into explaining that you may pass variables to the grabbed piece of template, that of course comes in the form of a block
source code from Ryan Bate's Calendar Screen-cast:
<div id="articles">
<h2 id="month">
<%= link_to "<", date: @date.prev_month %>
<%= @date.strftime("%B %Y") %>
<%= link_to ">", date: @date.next_month %>
</h2>
<%= calendar @date do |date| %>
<%= date.day %>
<% if @articles_by_date[date] %>
<ul>
<% @articles_by_date[date].each do |article| %>
<li><%= link_to article.name, article %></li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
In the code above, the block would be exclusively this part:
do |date| %>
<%= date.day %>
<% if @articles_by_date[date] %>
<ul>
<% @articles_by_date[date].each do |article| %>
<li><%= link_to article.name, article %></li>
<% end %>
</ul>
<% end %>
<% end %>
So, When he makes this call:
content_tag :td, view.capture(day, &callback), class: day_classes(day)
particularly:
view.capture(day, &callback)
What's happening here is that he's passing the day argument to the Block above as the |date| parameter (in the block).
What needs to be understood here, is that in the context of the Problem (making a 30-day Calendar); each day of the Month is passed to the capture method, along with the piece of template (&callback), doing so.. in consequence renders the block above for each day of a Given Month. The final step, of course is.. Placing that rendered content (for each day) as the content for the content_tag :td
A final note; Ryan is calling the capture method on a view variable, it isn't stated in the documentation either, but he does mention during the ScreenCast that he needs this view as a "proxy" to access the view, and of course the view is the only one that has access to ViewHelper methods.
So, in summary, it's very beautiful code, but it's only beautiful once you understand what it does, So, I agree is very confusing at first sight.
Hope this helps, it's the best explanation I could come up with. :)
这篇关于Rails:捕获方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!