当应用程序包含命名出口时,Ember JS无法按预期呈现嵌套出口

时间:2014-07-08 17:18:34

标签: ember.js nested outlet

鉴于以下观点:

<script type="text/x-handlebars">
    <article>{{outlet "foo"}}</article>
    <aside>{{outlet}}</aside>
</script>


<script type="text/x-handlebars" data-template-name="base/index">
    <h2>Base</h2>
    {{view Ember.Select
        contentBinding=model
        optionValuePath="content.id" optionLabelPath="content.name"
        prompt="Select a child"
        valueBinding="selectedChild"}}

    <div id="child">
      <p>I want the child rendering here</p>
      {{outlet}}
    </div>
</script>

<script type="text/x-handlebars" data-template-name="foo">
    <h2>Foo</h2>
</script>

<script type="text/x-handlebars" data-template-name="child">
    <h2>Child</h2>
    <p>Child: {{id}} {{name}}</p>
    <pre>{{controller}}</pre>
</script>

这个应用程序:

var App = Ember.Application.create({
    LOG_TRANSITIONS: true,
    LOG_ACTIVE_GENERATION: true,
    LOG_VIEW_LOOKUPS: true
});

App.Router.map(function() {
    this.resource('base', function() {
        this.resource('child', {path: ':child_id'});
    });
});

App.IndexRoute = Ember.Route.extend({
    beforeModel: function() {
        this.transitionTo('base');
    }
});

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

App.BaseIndexRoute = Ember.Route.extend({
    model: function() {
        return children;
    }
});

App.ChildController = Ember.ObjectController.extend();

App.BaseIndexController = Ember.ObjectController.extend({ 
    selectedChild: null,

    selectedChildChanged: function() {
        var id = this.get('selectedChild');
        this.transitionToRoute('child', id);
    }.observes('selectedChild')

});

App.ChildRoute = Ember.Route.extend({
    model: function(params) {
        return children[params.child_id - 1];
    }
});

var children = [
    {id: 1, name: 'Foo Goggins'},
    {id: 2, name: 'Bar McFudger'},
    {id: 3, name: 'Gia Goggins-McFudger'}
];

我希望将子视图渲染到{{outlet}}内的div#child,但它会渲染到主应用程序插座中。

您可以在此处查看一个有效的示例http://jsbin.com/docuj/10/edit

1 个答案:

答案 0 :(得分:1)

index路由是您资源下的实际路由,如果您导航得更深,则该索引路由将替换为更深路由的资源。您需要将其从index移动到资源路径本身。

App.BaseRoute = Ember.Route.extend({ 
  model: function() {
    return children;
  },
  renderTemplate: function() {
    this._super();

    this.render('foo', {into: 'application', outlet: 'foo'});
  }
});


App.BaseController = Ember.ObjectController.extend({ 
  selectedChild: null,

  selectedChildChanged: function() {
    var id = this.get('selectedChild');
    this.transitionToRoute('child', id);
  }.observes('selectedChild')

});

示例:http://jsbin.com/vilimete/1/edit

让我们尝试清理它,在资源下面你可以拥有资源或路线。路线下面没有任何东西,它们是一条死胡同。在这种特殊情况下,您没有定义基本资源或模板。 Ember是善良的,假设你想要一个基本模板,只需要它{{outlet}},然后它将基本索引路由渲染到该出口。当您切换到子资源时,它正在基础出口中呈现子资源。

这是一个可能描绘正在发生的事情的例子。 http://jsbin.com/xiqajawa/1/edit