2013-07-15 8 views
8

Qualcuno può spiegare in parole povere il modo in cui le prese annidate funzionano nei modelli di legno scuro?Percorsi nidificati in Rotaie di ambra e JS

In particolare cercando comprendere questo dalla documentazione: http://emberjs.com/guides/routing/rendering-a-template/

"Il percorso padre immediato non rendeva alla presa principale ..."

Ciò significa che il percorso attuale ha cercato di rendere nel modello di rotta genitore, ma la rotta principale non ha eseguito il rendering di un modello o, , se il modello fornito dall'itinerario principale non ha reso il rendering nel modello principale (ovvero, un valore predefinito {{outlet} }).

In particolare, sto cercando di capire come creare una gerarchia di viste nidificate nella mia app. È profondo tre strati di raccolte. Voglio creare una serie di viste nidificabili comprimibili, in base al contenuto delle raccolte. La struttura dei dati potrebbe essere come un albero.

Biblioteche -> ogni biblioteca ha molti Libri -> Ogni libro ha molte pagine

Cerchi un jsbin illustrativo o codice di esempio che dimostra la struttura modello annidato nella pratica.

Immaginate un router che assomiglia a questo:

App.Router.map(function() { 

    this.resource('libraries', function() { 
     this.route('new'); 

     this.resource('library', {path: ':library_id'}, function() { 

      this.resource('books', function() { 
       this.route('new'); 
       this.resource('book', {path: ':book_id'}, function() { 

        this.resource('pages', function() { 
         this.route('new'); 
         this.resource('page', {path: ':page_id'}, function() { 

         }); // Page 
        }); // Pages 

       }); // Book 
      }); // Books 

     }); // Library 
    }); // Libraries 

}); // map 

risposta

10

Nella maggior parte dei linguaggi di template generali forniscono un modo per avvolgere il contenuto target di una pagina in un layout principale. Ciò consente la separazione del layout di pagina comune in un altro file e il modello di destinazione più piccolo in un file diverso.

Ci sono state alcune iterazioni di questo in Ember, attualmente questa funzionalità è fornita dall'helper {{outlet}}. Gli outlet sono il modo di Ember per yield in un layout.

L'area dove outlet si discosta in modo significativo da yield si annida. Cedendo sul lato server è molto più semplice. Devi solo contrassegnare le aree di un modello da cedere e poi chiamare per ottenere un blocco di contenuto in quell'obiettivo designato.

Tuttavia, quando il rendering del contenuto viene passato a javascript sul lato client, solo le parti di una pagina vengono aggiornate su richiesta. Non è più possibile semplicemente yield direttamente nei marcatori. È necessario un codice più intelligente yield, ovvero: - outlet.

Ci sono 2 lati di uno {{outlet}}.

  1. Un indicatore che indica dove si desidera produrre. Questo è l'helper {{outlet}}.
  2. Codice che esegue il rendering di un modello in questa presa. Questo è il metodo render utilizzato all'interno del gancio renderTemplate.

Per impostazione predefinita, un {{outlet}} non ha bisogno di un nome. Questo lo rende lo sbocco predefinito per quel modello. Ci possono essere molti di questi punti vendita in un modello e possono essere specificati dandogli un nome.Ad esempio: -

{{outlet 'sidebar'}} 
{{outlet 'nav'}} 

Questo dichiara 2 uscite denominate "barra laterale" e "nav". Ora puoi rendere altri modelli in questi punti vendita.

Le prese predefinite vengono utilizzate durante il rendering senza un nome di presa esplicito. Per i punti vendita denominati, il rendering viene effettuato chiamando render in un hook renderTemplate di Route. L'operazione viene eseguita specificando un'opzione outlet in un hash passato al metodo render come opzioni.

renderTemplate() { 
    this.render('recentPosts', { outlet: 'sidebar' }); 
} 

Qui, il modello recentPosts saranno resi in una presa di nome 'sidebar' all'interno del suo modello di genitore.

Quando le rotte sono annidate all'interno di altre rotte nidificate, verranno renderizzate nella presa madre più vicina. Se la risorsa genitore non ha una presa predefinita, allora viene utilizzato il genitore e così via fino al raggiungimento del modello application.

Quando si dichiara una resource con this.resource('posts'); nel Router, si indica un paio di cose in base alla convenzione.

  1. rendere il percorso posts con il modello di layout posts.
  2. Se si desidera, eseguire il percorso implicito posts.index con il modello posts/index.

Il modello posts contiene un layout comune a tutti i post e le sue risorse secondarie. Al minimo deve contenere almeno una presa predefinita come, {{outlet}}.

Senza questo {{outlet}} percorsi figlio non avranno una presa genitore immediata da eseguire il rendering. Verranno quindi visualizzati nel genitore di quel genitore o in definitiva nello sbocco del modello application. Quando ciò accade, verrà visualizzato l'avviso "The immediate parent route did not render into the main outlet ...". Controlla la posizione del tuo outlets quando questo accade.

Il numero posts.index è un percorso implicito assegnato a tutte le risorse che hanno percorsi nidificati. In altre parole se la tua risorsa ha percorsi nidificati, non è necessario dichiarare esplicitamente un nidificato, this.route('index) `.

Questo itinerario index può visualizzare il contenuto di tale risorsa. Ad esempio, per posts.index, è possibile visualizzare un elenco di tutti posts. Un avvertimento secondario con questa via implicita è che il modello si trova sulla linea genitore posts. È necessario utilizzare l'API needs per ottenere questo modello nello PostsIndexController.

needs: ['posts'], 
contentBinding: 'controller.posts' 

Inoltre, questo itinerario posts.index è facoltativo. È possibile posizionare l'interfaccia utente da posts/index utilizzata per visualizzare un elenco di post, direttamente nel modello posts stesso. Tuttavia, ciò significa che qualsiasi risorsa secondaria eseguirà il rendering anche con l'elenco di post, accanto all'outlet in posts. La decisione se utilizzare o meno una route index esplicita dipende dall'interfaccia utente che deve essere visualizzata.

Sedere sopra tutti gli altri modelli è il modello application.Deve avere un outlet per le risorse nidificate da eseguire il rendering e in genere ospiterà il layout comune alla pagina. Se non si specifica un modello di applicazione, verrà utilizzato un modello predefinito. Questo modello generato è equivalente a {{outlet}}, vale a dire: - un modello con solo una presa predefinita.

Considerare i seguenti percorsi.

App.Router.map(function() { 
    this.resource('posts', function() { 
     this.route('new') 
     this.resource('post', {path: ':post_id'}, function() { 
     this.resource('comments', function() { 
      this.route('new'); 
     }); 
     }); 
    }); 
}); 

Qui, posts.new saranno resi in posts che sarà reso all'interno posts, che sarà reso in uscita di default del modello application. Il resto dei modelli utilizzati sono elencati di seguito.

+---------------------------+--------------------------------------------------------+ 
| Route      | Templates used (default outlets)      | 
+---------------------------+--------------------------------------------------------+ 
| posts.index    | posts.index > posts > application      | 
+---------------------------+--------------------------------------------------------+ 
| posts.new     | posts.new > posts > application      | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.index   | post.index > post > posts > application    | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.new   | post.new > post > posts > application     | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.comments.index | comments.index > comments > post > posts > application | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.comments.new | comments.new > comments > post > posts > application | 
+---------------------------+--------------------------------------------------------+ 

Questa gerarchia modello predefinito può essere modificato specificando un'opzione into al metodo render.

renderTemplate: function() { 
    this.render('posts', { into: 'sidebar' }) 
} 

Qui il modello posts renderà nella presa di default del modello sidebar.

Questo è tutto. Outlet è un altro concetto ember che utilizza una buona dose di convenzione sulla configurazione. Le impostazioni predefinite sono abbastanza buone, allo stesso tempo facili da personalizzare.

+0

Grazie per la panoramica dettagliata Darshan. La tabella Route -> Templates aiuta a chiarire qualcosa. Avrò letto questa coppia più tempo prima che lo faccia a pezzi. Ho solo bisogno di mantenere le cose dritte nella mia mente quando si tratta del comportamento di nidificazione. –

+0

dove hai definito il percorso "posts.post.new"? –

+0

@Darshan potresti anche guardare la mia domanda che riguarda anche il comportamento del router per emberjs? http://stackoverflow.com/questions/17780344/nested-routing-behavior-for-ember-js –