13

我有一个嵌套的路由层次结构,我的应用程序需要它来跟踪用户模型选择。我正在尝试使用主应用程序模板并将每个路由呈现到该模板上的单个插座中。这在我从父级到子级遍历路由层次结构时起作用。

但是,一旦您单击浏览器后退按钮以返回路由层次结构,父路由 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.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"
})}});

使用模板:

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

这是一个带有这段代码的jsfiddle。单击链接以遍历路线,然后单击浏览器后退按钮,应用程序模板被渲染,没有任何东西连接到它的出口。

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

有没有办法强制重新渲染,或者我是不是走错了路?

4

1 回答 1

29

你的做法是错误的。

Ember 依赖于与路由层次结构匹配的嵌套出口层次结构。因此,每次您单击将您带到子路由的链接时,子路由都应呈现到其父模板中的插座中。如果您总是渲染到相同的模板和插座,那么当您向上移动路由层次结构时,Ember 将无法正确更新插座。(我希望这是有道理的。)

为避免此问题,一个好的经验法则是仅使用into用于呈现您在路由层次结构之外管理的模板的选项。例如,我使用它来呈现没有 URL 并且我手动拆除的模式视图。在视图层次结构中,您几乎总是可以避免使用into. 例如,如果您需要使用单独的控制器渲染多个模板,则可以在模板中使用帮助程序,而不是在路由{{render}}中调用。render

在这种情况下,最简单的解决方案可能是将路由嵌套与模板嵌套匹配。你的animals/index路线 和pets真的是兄弟姐妹,而不是父子,pets/list和你的pets/new. 事实上,这是默认但有些隐藏的行为:您应该真正使用pets/index来呈现列表而不是父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'
});

使用模板:

<!-- 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>
于 2013-03-11T02:49:11.680 回答