Rails 3 - блок HAML, переданный в частичное отображение в исходном контексте вместо частичного - PullRequest
2 голосов
/ 13 декабря 2011

У меня есть часть, которая отображает таблицу, которую я хочу использовать на разных страницах.Некоторые представления, использующие его, должны вставлять дополнительные столбцы, поэтому я создал вспомогательные методы для добавления и извлечения новых заголовков столбцов и код для генерации

s на основе данных для текущей строки.

Помощникивыглядеть следующим образом:

def table_column table_name, column_name, &block
  raise "block required" unless block_given?
  @@tables ||= {}
  table = @@tables[table_name]
  if table.nil?
    @@tables[table_name] = table = []
  end
  index = table.size
  table[index] = [column_name, block]
end

def table_cells table_name
  table = @@tables[table_name] || []
  table.map { |column| column[0] }
end

def table_headers table_name
  table = @@tables[table_name] || []
  table.map { |column| column[1] }
end

Дробная часть использует хелперы, чтобы указать детали столбца перед рендерингом таблицы:

- table_column "tasks", "Name" do |task|
  %td= task.name

- table_column "tasks", "Start" do |task|
  %td= task.start_time.strftime(time_format)

- table_column "tasks", "End" do |task|
  %td= task.end_time.strftime(time_format)

%table
  %thead
    %tr
      - table_headers("tasks").each do |header|
        %th= header
  %tbody
    - @tasks.each do |task|
      %tr
        - table_cells("tasks").each do |cell|
          - cell.call(task)

Это прекрасно работает.Затем у меня появляется представление, которое добавляет столбец перед рендерингом частичного:

- table_column "tasks", "ID" do |task|
  %td=task.id

= render "table"

Переменная task из частичного используется при рендеринге столбца идентификаторов, но по какой-то причине ячейки идентификаторовполучить выше таблицы!Полученный HTML-код похож на этот:

<td>10001</td>
<td>10002</td>
<td>10003</td>
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Start</th>
      <th>End</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Steal underpants</td>
      <td>Feb.12, 2012</td>
      <td>Jun.07, 2012</td>
    </tr>
    <tr>
      <td>???</td>
      <td>Jun.08, 2012</td>
      <td>Nov.13, 2012</td>
    </tr>
    <tr>
      <td>Profit!</td>
      <td>Nov.14, 2012</td>
      <td>Jan.23, 2013</td>
    </tr>
  </tbody>
</table>

Как будто средство визуализации HAML запоминает исходный контекст блока, переданного в table_column , но только при передаче извне партиала.В качестве теста я переместил код столбца ID в частичное, и в этом случае он работает.Я также пытался передать строки вместо блоков в table_column (работает), но я действительно предпочел бы передать блок HAML, так как код, который мне нужно использовать в конце, будет намного сложнее,Любые идеи будут оценены.

1 Ответ

0 голосов
/ 15 декабря 2011

HAML немедленно рендерит вызов table_column вместо простого добавления блока в @@ tables.Я полагаю, что это происходит потому, что когда вы вызываете блок из партиала, он отображается в контексте представления, в котором вы определили блок, а не сам партиал.Лучший подход может состоять в том, чтобы условно иметь столбцы частичного добавления в зависимости от локальных элементов, которые вы передаете ему:

- if defined?(id) && id
  - table_column "tasks", "ID" do |task|
    %td=task.id

- table_column "tasks", "Name" do |task|
  %td= task.name

- table_column "tasks", "Start" do |task|
  %td= task.start_time.strftime(time_format)

- table_column "tasks", "End" do |task|
  %td= task.end_time.strftime(time_format)

%table
  %thead
    %tr
      - table_headers("tasks").each do |header|
        %th= header
  %tbody
    - @tasks.each do |task|
      %tr
        - table_cells("tasks").each do |cell|
          - cell.call(task)

В этом случае столбец идентификатора отображается только в том случае, если в локальное имя id передаетсячастичное и установленное в true, а столбцы Name, Start и End будут отображаться всегда.Затем вы бы назвали частичное как:

render "table" # Only renders the Name, Start & End columns

или

render "table", :id => true # Renders the ID, Name, Start, & End columns
...