2013-03-01 2 views
13

Ich habe eine verschachtelte Routenhierarchie, die ich für meine Anwendung brauche, um Benutzermodellauswahlen zu verfolgen. Ich versuche, eine Hauptanwendungsvorlage zu verwenden und jede Route in einem einzigen Absatz auf dieser Vorlage rendern zu lassen. Dies funktioniert, wenn ich die Routenhierarchie von einem Elternteil zum nächsten durchlaufe.Verschachtelte Routen, die im Browser auf die gleiche Vorlage/Ausgangspausen übertragen werden Zurück Schaltfläche klicken

Sobald Sie jedoch auf die Zurück-Schaltfläche des Browsers klicken, um die Routenhierarchie wieder aufzurufen, wird der Hook der übergeordneten Route renderTemplate nicht ausgelöst. Dies führt dazu, dass das Kind aus der Steckdose ausgehängt wird und nichts zurück in es gerendert wird.

Hier ist ein Beispiel:

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" 
})}}); 

Mit Vorlagen:

<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> 

Und hier ist ein jsfiddle mit diesem Code. Klicken Sie auf die Links, um die Routen zu durchlaufen, klicken Sie dann auf die Schaltfläche Zurück des Browsers, und die Anwendungsvorlage wird gerendert, ohne dass eine Verbindung mit der Datei besteht.

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

Gibt es eine Möglichkeit ein erneuten machen zu zwingen, oder soll ich das über den falschen Weg?

Antwort

29

Sie gehen in die falsche Richtung.

Ember hängt von einer Hierarchie verschachtelter Ausgänge ab, die der Routenhierarchie entsprechen. Jedes Mal, wenn Sie auf einen Link klicken, der Sie zu einer untergeordneten Route führt, sollte die untergeordnete Route in eine Steckdose innerhalb der Vorlage des übergeordneten Elements gerendert werden. Wenn Sie immer in dasselbe Template und Outlet rendern, kann Ember die Outlets nicht korrekt aktualisieren, wenn Sie sich in der Routenhierarchie nach oben bewegen. (Ich hoffe, das ergibt Sinn.)

Um dieses Problem zu vermeiden, empfiehlt es sich, nur die into-Option zum Rendern von Vorlagen zu verwenden, die Sie außerhalb der Routenhierarchie verwalten. Zum Beispiel verwende ich es zum Rendern modaler Ansichten, die keine URL haben und die ich manuell abreiße. Innerhalb der View-Hierarchie können Sie fast immer vermeiden, into zu verwenden. Wenn Sie beispielsweise mehr als eine Vorlage mit einem separaten Controller rendern müssen, können Sie den Helper {{render}} in Ihrer Vorlage verwenden, anstatt render in Ihrer Route aufzurufen.

In diesem Fall ist es wahrscheinlich die einfachste Lösung, die Verschachtelung Ihrer Route mit der Verschachtelung Ihrer Vorlage zu vergleichen. Ihre animals/index Route und pets sind wirklich Geschwister, nicht Eltern-Kind, und das gleiche für pets/list und Ihre pets/new. In der Tat ist dies das voreingestellte, aber etwas versteckte Verhalten: Sie sollten pets/index verwenden, um die Liste anstelle der übergeordneten Route pets zu rendern.

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' 
}); 

Mit Vorlagen:

<!-- 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> 
Verwandte Themen