Domanda

Io sono l'attuazione di un cruscotto come un parente newbie Rails (più di un ragazzo infrastrutture). Il cruscotto sarà composto da più pagine, ciascuna pagina dei quali conterrà più grafici / tabelle / etc. Per la modularità, io voglio che sia il più semplice possibile aggiungere nuovi grafici o modificare le visualizzazioni dei dati.

Di 'una pagina ha 5 diversi grafici. Avrei potuto fare il controllore 5 ricerche di dati separati, contenere tutti i dati rilevanti in variabili di istanza, e renda 5 parziali, ognuno dei quali toccano sottoinsiemi di dati. Ma sembra più modulare di avere uno "index" azione di controllo la cui rendering ha un sacco di div, e per ogni div c'è un'altra azione di controllo che fa la ricerca di dati e ha una vista associata parziale incaricato di gestire la visualizzazione di tali dati all'interno della div.

Quindi, se sto mostrando la pagina dashboard sito web che ha due grafici, website/index userebbe website/graph1 e website/graph2 per cercare i dati per ciascuna e quindi _graph1.html.erb e _graph2.html.erb avrebbe utilizzato i dati del controller di compilare div "graph1" e "graph2", ecc .

E 'questo il progetto giusto, e se sì, qual è il modo più semplice per ottenere questo risultato? Ho un'approssimazione usando remote_function con :action => "graph1" di compilare div, ma sono felice al 100% con esso. Ho il sospetto che mi manca qualcosa di più facile che Rails farà per me.

È stato utile?

Soluzione

Versione 1:

metodo semplice che in realtà ho usato nella produzione: iframe

.

La maggior parte delle volte in realtà non importa se la pagina rende tutto in una volta e direttamente dal server, e in effetti è meglio che si carichi sfalsati.

Se hai appena cadere uno src'd iframe per mostrare l'azione del controller, si dispone di una soluzione molto semplice che non richiede diretti interazioni cross-controller.

Pro:

  • morto facile
  • lavora con azioni Mostra esistenti etc
  • potrebbe anche essere più veloce, a seconda di risparmio w / parallelo vs richieste sequenziali e carico di memoria etc

Contro:

  • non si può sempre facilmente salvare la pagina con qualunque-cosa-è
  • iframe scoppierà del namespace javascript della pagina host, quindi se hanno bisogno di questo, potrebbe essere necessario dare loro il proprio layout minimalista; essi, inoltre, non saranno in grado di influenzare la pagina circostante di fuori del loro iframe
  • potrebbe essere più lento, a seconda del tempo di ping etc
  • potenziale bug n + 1 efficienza se si dispone di molti di questi moduli in una pagina

Versione 2:

Fare la stessa cosa usando JS chiama per sostituire un div con un parziale di, à la:

<div id="placeholder">
<%= update_page {|page| page['placeholder'].replace with some partial call here } %>

Come sopra, ad eccezione di:

Pro:

  • non si blocca in un iframe, quindi contesto azioni JS etc
  • consente una migliore gestione dei casi di insufficienza

Con:

  • richiede JS e segnaposto div; un po 'più complesso

Versione 3:

Chiama un sacco di parziali. Diventa complicato per fare che una volta che si sta parlando di cose come cruscotti in cui i singoli moduli hanno una notevole quantità di logica di impostazione, tuttavia.

Ci sono vari modi per aggirare questo facendo quelle cose in 'mixins' o simili, ma IMO sono un po kludgy.

ETA: Il modo per farlo via mixins è quello di creare ciò che è essenzialmente un file di libreria che implementa i controller del modulo funzioni di configurazione, comprendono che ovunque qualcosa che chiama 'em è usato, e lo chiamano' em

.

Tuttavia, questo ha inconvenienti:

  • è necessario sapere che cosa migliori azioni di controllo a livello provocheranno pagine che includono i moduli (che si potrebbe non facilmente, se queste sono le cose davvero widgety che potrebbero apparire in tutto, ad esempio le preferenze dell'utente dipendente)
  • in realtà non agisce come regolatore a pieno titolo
  • si mischiano ancora un sacco di logica in cui la vostra passione partecipazione ha bisogno di conoscere le cose che sono in possesso di
  • non si può facilmente farlo essere segregata in un proprio controllore, perche' ha bisogno di essere in un file di libreria di tipo / mixin

E 'possibile chiamare i metodi in un controller da un altro controllore. Tuttavia, è un grande dolore nel culo, e un importante kludge. L'unica volta che si dovrebbe prendere in considerazione di farlo è se a) sono entrambi i controller necessari in modo indipendente nei propri diritti, e b) ha di funzionare del tutto sul back-end.

Ho dovuto fare una volta - in primo luogo perché il refactoring il motivo era ancora più di un dolore -. E ti prometto che non vuole andare lì a meno che non si deve

Sommario

Il metodo migliore IMHO è la prima se si dispone di abbastanza cose complesse che richiedono l'installazione significativo - un semplice iframe che visualizza il modulo, passando un parametro per dirgli di utilizzare un layout ultraminimalist (solo CSS + header JS), perché è non essere visualizzato come una propria pagina.

Questo consente di mantenere le cose totalmente indipendente, la funzione più o meno come se fossero perfettamente normali controllori del proprio (diversi dalla impostazione di layout), conservare vie normali, ecc.

Se NON è necessario l'installazione significativo, poi basta usare parziali, e passare in qualunque di cui hanno bisogno come variabile locale. Questo inizierà a ottenere fragile se si esegue in cose come bug n + 1 di efficienza, anche se ...

Altri suggerimenti

perché non si dà Apotomo una prova, che è i widget stateful per Rails:

Un tutorial su come costruire un semplice dashboard

Si potrebbe ottenere questo utilizzando

render_output = render: action => "Graph2"

Ma me personalmente probabilmente avvolgere il codice sia un aiutante condiviso o scrivere la propria "lib" nella directory lib di riutilizzare il codice con un modello condiviso. Ricordate che se non si cambia il file route.rb qualsiasi metodo pubblico definito è accessibile da

/ regolatore / action /: id

Inoltre ricordarsi di spegnere il layout per la funzione: layout => nil (o specificate nella parte superiore del layout controllore "grafico",: eccetto => [ "graph2"]

Saluti

Christian

Io non sono a conoscenza di particolari Rails trucchi per raggiungere questo obiettivo senza utilizzare AJAX nel modo che ho descritto.

Il modo più semplice per ottenere la modularità che cercate è quello di mettere quelle porzioni di codice del controller in metodi separati (ad esempio set_up_graph1_data, set_up_graph2_data, ecc), che è sufficiente chiamare dalla vostra azione index per impostare le variabili per la vista.

È possibile inserire questi metodi in ApplicationController se si vuole a disposizione di più controllori.

Come nota a margine, nella fase iniziale, Rails ha usato per avere una funzionalità denominata 'componenti' che permetterebbero di fare esattamente quello che stai chiedendo qui, senza dover utilizzare AJAX. Dalla vostra vista, si può solo rendere un'altra azione di controllo, in linea. Tuttavia, questa funzionalità è stata rimossa per motivi di prestazioni e filosofia di design.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top