Как создать собственный блок помощника с двумя или более вложенными дочерними элементами? - PullRequest
2 голосов
/ 28 августа 2011

Я бы хотел, чтобы что-то подобное было в моих взглядах:

<%= helper_a do |ha| %>
  Content for a
  <%= ha.helper_b do |hb| %>
    Content for b
    <%= hb.helper_c do |hc| %>
      Content for c
      ... and so on ...
    <% end %>
  <% end %>
<% end %>

Чтобы получить, например, это:

<tag_a>
  Content for a
  <tag_b class="child_of_tag_a">
    Content for b
    <tag_c class="nested_child_of_tag_a child_of_tag_b">
      Content for c
    </tag_c>
  </tag_b>
</tag_a>

Это означает, что каждый уровень имеет доступ к некоторой информации уровня выше (поэтому они являются вложенными и не полностью автономными методами)

Я знаю, как создать простого помощника:

def helper_a(&block)
  content = capture(&block)
  content_tag :tag_a, content
end

И я знаю, что могу передать свои аргументы capture, чтобы использовать их в представлении, так что-то вроде этого, чтобы получить |ha| моего примера

def helper_a(&block)
  content = capture(OBJECT_HERE, &block)
  content_tag :tag_a, content
end

Но где я могу определить это OBJECT_HERE, особенно класс для него, и как это может продолжаться с несколькими уровнями захвата каждого блока?

1 Ответ

1 голос
/ 28 августа 2011

Я придумал пару решений, но я далеко не эксперт в системе шаблонов Rails.

Первый использует переменную экземпляра:

def helper_a(&block)
  with_context(:tag_a) do
    content = capture(&block)
    content_tag :tag_a, content
  end
end

def helper_b(&block)
  with_context(:tag_b) do
    content = capture(&block)
    content_tag :tag_b, content
  end
end

def helper_c(&block)
  with_context(:tag_c) do
    content = capture(&block)
    content_tag :tag_c, content
  end
end

def with_context(name)
  @context ||= []
  @context.push(name)
  content = yield
  @context.pop
  content
end

который используется следующим образом:

<%= helper_a do %>
  Content for a
  <%= helper_b do %>
    Content for b
    <%= helper_c do %>
      Content for c
      ... and so on ...
    <% end %>
  <% end %>
<% end %>

И другое решение, которое передает контекст на каждом шаге:

def helper_a(context = [], &block)
  context = capture(context.push(:tag_a), &block)
  content_tag(:tag_a, content)
end

def helper_b(context = [], &block)
  context = capture(context.push(:tag_b), &block)
  content_tag(:tag_b, content)
end

def helper_c(context = [], &block)
  context = capture(context.push(:tag_c), &block)
  content_tag(:tag_c, content)
end

, которое используется таким образом:

<%= helper_a do |context| %>
  Content for a
  <%= helper_b(context) do |context| %>
    Content for b
    <%= helper_c(context) do |context| %>
      Content for c
      ... and so on ...
    <% end %>
  <% end %>
<% end %>

Но я бы действительно советовал не использовать ни одно из этих решений, если все, что вы делаете, это стилизация CSS и / или манипулирование Javascript.Это действительно усложняет помощников, может привести к ошибкам и т. Д.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...