2013-03-01 4 views
13

Ho una gerarchia di route nidificata che mi serve per la mia applicazione per tenere traccia delle selezioni del modello utente. Sto provando a utilizzare un modello di applicazione principale e a rendere ogni route in una singola presa su quel modello. Funziona mentre attraverso la gerarchia del percorso da genitore a figlio.Il rendering dei percorsi nidificati nello stesso modello/interruzioni di output sul pulsante di scelta del browser indietro

Tuttavia, una volta fatto clic sul pulsante Indietro del browser per tornare alla gerarchia del percorso, l'hook di renderingTemplate del percorso principale non viene attivato. Ciò si traduce nel fatto che il bambino viene sganciato dalla presa e nulla viene restituito.

Ecco un esempio:

App = Ember.Application.create({}); 

App.Router.map(function(){ 
    this.resource("animals", function(){ 
     this.resource("pets", function(){ 
       this.route('new') 
     }) 
    }) 
}); 
App.PetsView = Ember.View.extend({ 
    templateName : 'wild/pets' 
}); 
App.AnimalsRoute = Ember.Route.extend({ 
    renderTemplate: function() { 
    this.render({ 
    into: "application", 
    outlet : "A" 
}) 
    }}); 
App.PetsRoute = Ember.Route.extend({ 
    renderTemplate: function() { 
this.render({ 
    into: "application", 
    outlet : "A" 
})}}); 

App.PetsNewRoute = Ember.Route.extend({ 
    renderTemplate: function() { 
this.render({ 
    into: "application", 
    outlet : "A" 
})}}); 

Con i modelli:

<script type="text/x-handlebars" data-template-name="application"> 
    <h1>{{#linkTo "animals"}}Hello from Ember.js</h1>{{/linkTo}} 
     {{outlet A}} 
</script> 

<script type="text/x-handlebars" data-template-name="animals"> 
    {{#linkTo "pets"}}This is animals list{{/linkTo}} 
</script> 
<script type="text/x-handlebars" data-template-name="wild/pets"> 
    {{#linkTo "pets.new"}}This is pets list{{/linkTo}} 
</script> 

<script type="text/x-handlebars" data-template-name="pets/new"> 
    This is pet creation 
</script> 

Ed ecco un jsfiddle con questo codice. Fare clic sui collegamenti per attraversare i percorsi, quindi fare clic sul pulsante Indietro del browser e il modello dell'applicazione viene visualizzato con niente agganciato alla propria presa.

http://jsfiddle.net/Wq6Df/3/

C'è un modo per forzare una ri-renderizzare, o sto andando su questo nel modo sbagliato?

risposta

29

Stai andando sul modo sbagliato.

Ember dipende da una gerarchia di prese annidate che corrispondono alla gerarchia del percorso. Pertanto, ogni volta che fai clic su un link che ti indirizza a una rotta secondaria, la route secondaria deve essere visualizzata in una presa all'interno del modello del genitore. Se si esegue sempre il rendering nello stesso modello e nello stesso punto di uscita, Ember non sarà in grado di aggiornare correttamente le prese quando si esegue il backup della gerarchia del percorso. (Spero che abbia senso.)

Per evitare questo problema, una buona regola empirica è utilizzare l'opzione into per il rendering dei modelli che si gestiscono al di fuori della gerarchia del percorso. Ad esempio, lo uso per il rendering di viste modali che non hanno un URL e che abbatto manualmente. All'interno della gerarchia delle viste, è quasi sempre possibile evitare di utilizzare into. Ad esempio, se è necessario eseguire il rendering di più modelli con un controller separato, è possibile utilizzare l'helper {{render}} all'interno del modello anziché chiamare render nel percorso.

In questo caso, la soluzione più semplice è probabilmente quella di associare il nesting del percorso al nesting del modello. Il tuo itinerario animals/index e pets sono davvero fratelli, non genitore-figlio, e lo stesso per pets/list e il tuo . In effetti, questo è il comportamento predefinito, ma in qualche modo nascosto: dovresti utilizzare davvero lo pets/index per eseguire il rendering dell'elenco anziché la rotta principale pets.

App = Ember.Application.create({}); 

App.Router.map(function(){ 
    this.resource("animals", function(){ 
     // this.route("index"); at path /animals is implicit 
     this.resource("pets", function(){ 
       // this.route("index"); at path /animals/pets is implicit 
       this.route("new") 
     }) 
    }) 
}); 

// You don't really need any of these route definitions now; 
// I'm including them for clarity 
App.AnimalsRoute = Ember.Route.extend(); 
App.AnimalsIndexRoute = Ember.Route.extend(); 

App.PetsRoute = Ember.Route.extend(); 
App.PetsIndexRoute = Ember.Route.extend(); 
App.PetsNewRoute = Ember.Route.extend(); 

// Not sure why you need to use a custom template name here, 
// but it should work fine 
App.PetsView = Ember.View.extend({ 
    templateName : 'wild/pets' 
}); 

Con i modelli:

<!-- animals gets rendered into this outlet --> 
<script type="text/x-handlebars" data-template-name="application"> 
    <h1>{{#linkTo "animals"}}Hello from Ember.js</h1>{{/linkTo}} 
    {{outlet}} 
</script> 

<!-- animals/index and pets get rendered into this outlet --> 
<script type="text/x-handlebars" data-template-name="animals"> 
    {{outlet}} 
</script> 

<!-- no outlet here because animals/index has no child routes --> 
<script type="text/x-handlebars" data-template-name="animals/index"> 
    {{#linkTo "pets"}}This is animals list{{/linkTo}} 
</script> 

<!-- pets/index and pets/new get rendered into this outlet --> 
<script type="text/x-handlebars" data-template-name="wild/pets"> 
    {{outlet}} 
</script> 

<script type="text/x-handlebars" data-template-name="pets/index"> 
    {{#linkTo "pets.new"}}This is pets list{{/linkTo}} 
</script> 

<script type="text/x-handlebars" data-template-name="pets/new"> 
    This is pet creation 
</script>