2012-05-25 10 views
6

Sto provando a creare un contenuto dinamico con yield e content_for. Fondamentalmente ho un sacco di layout. E non voglio creare un mucchio di viste per ogni layout. Voglio rendere visibili le parti quando sono necessarie. Per diverse parti del codice è ok. Ma ho problemi con le stesse parti con contenuti diversi.Passare i parametri a cedere in Rails 3 (o è possibile?)

nel mio application.html.erb

<%= yield %> 
<%= yield :name_section %> 

E nella mia show.html.erb ho;

<% content_for :name_section do %> 
    <b>Name:</b> 
    <%= @post.name %> 
<% end %> 

Ecco la domanda;

E se voglio più nome_una sezione con contenuti diversi. Intendo; Voglio mettere :name_section luoghi diversi nella mia vista con contenuti diversi.

Per ex;

<table> 
    <tr> 
    <td> 
     <%= yield :name_section %> 
    </td> 
    </tr> 
    <tr> 
    <td> 
     <%= yield :name_section %> 
    </td> 
    </tr> 
</table> 

Qualche idea?

Grazie. Çağdaş

+0

perché hanno bisogno dello stesso nome? Certo il rubino fa magie ma legge le menti. – drhenner

+0

con nomi diversi devo duplicare il mio codice. ma penso di risolvere questo problema con gli aiutanti. grazie per la risposta comunque. –

+0

non dimenticare di non duplicare il codice e la singola responsabilità sono entrambi importanti – drhenner

risposta

2

La seguente soluzione ha funzionato bene per me. Non ti permette di passare argomenti, ma se, proprio prima di chiamare content_for (la seconda volta), assegni i tuoi argomenti alle variabili di istanza, questo ti permette di fare riferimento alle variabili di istanza in content_for. L'idea di base è che content_for generi il contenuto quando viene chiamato la prima volta e che il contenuto rimanga statico, ma questa soluzione temporanea ritarda la generazione di contenuto statico finché non si è pronti a visualizzare il contenuto.

In primo luogo, aggiungere questa funzione al modulo aiutante:

def immediate_content_for name, content = nil, &block 
    @immediate_content ||= {} 
    if content || block_given? then 
    @immediate_content[name] = Proc.new { content_for name, content, &block } 
    nil 
    else 
    @immediate_content[name].call 
    content_for name 
    end 
end 

Quindi, si supponga di voler passare a arg1content_for. È ora possibile fare questo:

<% content_for :my_form %> 
    <%= some_helper_function(@arg1) %> 
<% end %> 

Poi, più avanti nel codice, dopo la vostra definito arg1:

<%= @arg1 = arg1 %> 
<%= content_for :my_form %> 

Si tratta di un hack, nel senso che non posso garantire che il comportamento di immediate_content_for è in ogni altro modo identico a quello di content_for, e se il comportamento di content_for cambia in alcune versioni future di binari, sarà necessario aggiornare immediate_content_for se si desidera che continui il mirroring content_for. Anche se non è una soluzione ottimale, fa il lavoro per ora.