Rails:捕获方法 [英] Rails: capture method

查看:35
本文介绍了Rails:捕获方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码来自 Ryan Bates 的 RailsCasts,其中他把博客的首页变成了日历,这样文章就会在几天内显示为链接.以下帮助器模块创建日历.我对这段代码有两个疑问

  1. 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

  1. In the day_cell method, he uses a method called capture. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆