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

人盡茶涼 提交于 2019-11-28 04:46:40

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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!