嵌套的路线渲染到相同的模板/插座中断浏览器返回按钮点击 [英] Nested routes rendering into same template/outlet breaks on browser back button click

查看:67
本文介绍了嵌套的路线渲染到相同的模板/插座中断浏览器返回按钮点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个嵌套的路由层次结构,我需要我的应用来跟踪用户模型选择。我试图使用主应用程序模板,并将每个路线渲染到该模板的单个插座。但是,一旦你点击浏览器返回按钮来返回路由层次结构,父路由renderTemplate钩子就不会不要开火了这导致孩子从出口解开,没有任何东西退回。



这里有一个例子:

  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.PetsRou​​te = Ember.Route.extend({
renderTemplate:function(){
this.render({
into:application,
outlet: A
})}});

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

带有模板:

 < script type =text / x-handlebarsdata-template-name =application> 
< h1> {{link toanimals}}您好,来自Ember.js< / h1> {{/ linkTo}}
{{outlet A}}
< / script> ;

< script type =text / x-handlebarsdata-template-name =animals>
{{#linkTopets}}这是动物列表{{/ linkTo}}
< / script>
< script type =text / x-handlebarsdata-template-name =wild / pets>
{{#linkTopets.new}}这是宠物清单{{/ linkTo}}
< / script>

< script type =text / x-handlebarsdata-template-name =pets / new>
这是宠物创作
< / script>

这里是一个jsfiddle这个代码。单击链接遍历路由,然后单击浏览器返回按钮,并将应用程序模板呈现无任何挂钩。



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



有没有办法强制重新或者我是这样做的错误的方式?

解决方案

你会这样做错误的方式。 p>

Ember取决于匹配路由层次结构的嵌套出口的层次结构。因此,每当您点击链接到您的子路径时,子路由应该呈现在其父模板中的插座中。如果您始终渲染为相同的模板和插座,则当您重新启动路由层次结构时,Ember将无法正确更新插座。 (我希望这是有道理的。)



为避免这个问题,一个很好的经验法则是只使用用于渲染您在路由层次结构外部管理的模板的选项。例如,我使用它来呈现没有URL的模式视图,我手动删除。在视图层次结构中,几乎可以避免使用。例如,如果您需要使用单独的控制器渲染多个模板,则可以在模板中使用 {{render}} 帮助器,而不是调用<$ c $在您的路由中,c> render 。



在这种情况下,最简单的解决方案可能是将路由嵌套与模板嵌套相匹配。 动物/索引路线和宠物真的是兄弟姐妹,而不是父母,而和您的 pets / new 。事实上,这是默认但有些隐藏的行为:您应该真正使用 pets / index 来呈现列表而不是父 pets route。

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

App.Router.map(function(){
this.resource(animals,function(){
// this.route(index); at路径/动物是隐式
this.resource(pets,function(){
// this.route(index);在路径/动物/宠物是隐含的
这个。 route(new)
})
})
});

//您现在不需要任何这些路由定义;
//我要包括他们为了清楚
App.AnimalsRoute = Ember.Route.extend();
App.AnimalsIndexRoute = Ember.Route.extend();

App.PetsRou​​te = Ember.Route.extend();
App.PetsIndexRoute = Ember.Route.extend();
App.PetsNewRoute = Ember.Route.extend();

//不知道为什么你需要在这里使用自定义模板名称,
//但它应该工作正常
App.PetsView = Ember.View.extend({
templateName:'wild / pets'
});

带有模板:

 <! - 动物被渲染到这个插座 - > 
< script type =text / x-handlebarsdata-template-name =application>
< h1> {{link toanimals}}您好,来自Ember.js< / h1> {{/ linkTo}}
{{outlet}}
< / script>

<! - 动物/指数和宠物被渲染到这个插座 - >
< script type =text / x-handlebarsdata-template-name =animals>
{{outlet}}
< / script>

<! - 由于动物/索引没有儿童路线,因此没有出口 - >
< script type =text / x-handlebarsdata-template-name =animals / index>
{{#linkTopets}}这是动物列表{{/ linkTo}}
< / script>

<! - 宠物/指数和宠物/新的呈现到这个插座 - >
< script type =text / x-handlebarsdata-template-name =wild / pets>
{{outlet}}
< / script>

< script type =text / x-handlebarsdata-template-name =pets / index>
{{#linkTopets.new}}这是宠物清单{{/ linkTo}}
< / script>

< script type =text / x-handlebarsdata-template-name =pets / new>
这是宠物创作
< / script>


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 a single outlet on that template. This works as I traverse down the route hierarchy from parent to child.

However once you click the browser back button to go back up the route hierarchy the parent route renderTemplate hook doesn't fire. This results in the child being unhooked from the outlet and nothing rendered back into it.

Here's an example:

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

With templates:

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

And here's a jsfiddle with this code. Click the links to traverse the routes, then click the browser back button and the application template is rendered with nothing hooked into its outlet.

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

Is there any way to force a re-render, or am I going about this the wrong way?

解决方案

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>

这篇关于嵌套的路线渲染到相同的模板/插座中断浏览器返回按钮点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆