Nested routes rendering into same template/outlet breaks on browser back button click

后端 未结 1 1588
盖世英雄少女心
盖世英雄少女心 2020-12-08 05:58

I have a nested route hierarchy that I need for my application to track user model selections. I\'m trying to use a main application template and have each route render into

相关标签:
1条回答
  • 2020-12-08 05:59

    You're going about it the wrong way.

    Ember depends on a hierarchy of nested outlets that match the route hierarchy. So every time you click on a link that takes you to a child route, the child route should render into an outlet within its parent's template. If you always render into the same template and outlet, then Ember won't be able to update the outlets properly when you move back up the route hierarchy. (I hope that makes sense.)

    To avoid this problem, a good rule of thumb is to only use the into option for rendering templates that you're managing outside of the route hierarchy. For example, I use it for rendering modal views that don't have a URL and which I tear down manually. Within the view hierarchy, you can almost always avoid using into. For example, if you need to render more than one template with a separate controller, you can use the {{render}} helper within your template instead of calling render in your route.

    In this case, the easiest solution is probably to match your route nesting to your template nesting. Your animals/index route and pets are really siblings, not parent-child, and same for pets/list and your pets/new. In fact, this is the default but somewhat hidden behaviour: you should really be using pets/index to render the list instead of the parent pets route.

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

    With templates:

    <!-- 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>
    
    0 讨论(0)
提交回复
热议问题