我正在关注 Ember 2.3 的文档,似乎在任何地方都找不到非常基本的东西:如何在主模板中访问路由的模型钩子提供的值:application.hbs
?
路由/客户端.js
// ...
export default Ember.Route.extend({
model() {
return {
navigation: [
{
title: "Projects",
link: "projects"
},
{
title: "My Specifications",
link: "specs"
}
]
}
}
});
模板/应用程序.hbs
<nav>
{{#each navigation as |navItem|}}
<li>{{#link-to navItem.link}} {{navItem.title}} {{/link-to}}</li>
{{/each}}
</nav>
{{outlet}}
与现在一样,导航对象可由路由的模板 ( client.hbs
( 访问,但不能由应用程序模板访问。
它是如何完成的(除非 ember 在未来的版本中想出更好的方法(:
路由/客户端.js
// ...
export default Ember.Route.extend({
setupController() {
this.controllerFor('application').set('navigation', ["nav1", "nav2"]);
}
});
谢谢,伊万,你的答案!
如何访问主模板中路由的模型钩子提供的值
默认情况下,在路由的setupController
钩子内,Ember 会将控制器上的属性model
设置为从路由的model
钩返回的承诺的解析值。
这意味着您可以使用模板中的属性model
来访问model.navigation
:
<nav>
{{#each model.navigation as |navItem|}}
<li>{{#link-to navItem.link}} {{navItem.title}} {{/link-to}}</li>
{{/each}}
</nav>
如果要使用其他名称,可以覆盖 setupController
钩子并自行设置名称:
export default Ember.Route.extend({
// ...
setupController(controller, model) {
this.set('navigation', Ember.get(model, 'navigation'));
}
// ... rest of the code
})
这意味着您现在可以在模板中使用navigation
而不是model.navigation
。另一种方法是在控制器内为 model
属性添加别名:
export default Ember.Controller.extend({
navigation: Ember.computed.alias('model.navigation')
// ... rest of the code
})
这也将允许您使用 navigation
而不是 model.navigation
.
但是,如果要在应用程序中具有某种全局导航,更好的方法是使用注入到任何需要导航的控制器中的Service
。像这样:
// app/services/navigation.js
export default Ember.Service.extend({
items: null,
init() {
this._super(...arguments);
this.set('items', [{
title: "Projects",
link: "projects"
}, {
title: "My Specifications",
link: "specs"
}]);
}
});
然后将其注入控制器中:
export default Ember.Controller.extend({
navigation: Ember.service.inject()
});
现在,您还可以访问该控制器模板中的导航。
我会像这样解决这个问题。创建接受自定义参数的导航组件。
模板应用程序.hbs
{{custom-navigation url=apiURL user=user}}
现在在你的客户端中.js
apiURL: 'navigations/client'
以及您的自定义组件自定义导航.js
resolvedRouteNavs: function() {
return DS.PromiseArray.create({
promise: store.query(this.get('url'), { user? : userID?? });
})
}.property('apiURL')
和自定义导航.hbs。
{{#each resolvedRouteNavs as |navItem|}}
{{navItem.name}}
{{/each}}
如果您将静态数组作为导航进行处理
然后不需要解析,只需输出绑定数组,每个路由都不同。
客户端.js
navs: [{ name: '1', route: 'foo'}, { name: '2', route: 'bar' }]
一些不同的地方.js
navs: [{ name: 'blah', route: 'foo.bar'}, { name: 'meh', route: 'bar.foo' }]
实际上,模型钩子应该包含从服务器检索的数据。否则使用安装程序控制器挂钩。
setupController: function(controller, model) {
this._super(controller, model);
controller.setProperties({
nav: []
});
我最近需要解决这个问题,这就是我的做法。
首先,这是我的application.hbs
模板中的内容:
` <!-- app/templates/application.hbs -->
<div class="page">
{{!-- Main site navigation menu --}}
{{app-navbar isHidden=hidesNavbar}}
{{!-- Site content overrides this block --}}
{{outlet}}
{{!-- Main site footer --}}
{{app-footer isHidden=hidesFooter}}
</div>`
在我的应用中,app-navbar
和 app-footer
都是知道如何使用 isHidden
属性使自己可见或不可见的组件。切换可见性有不同的方法,但为了简洁起见,让我们将任一组件的内容包装在条件块中,如下所示:
`<!-- app-navbar and app-footer -->
{{#unless isHidden}}
<!-- component HTML here -->
{{/unless}}
`
现在,从我不想看到app-navbar
或app-footer
的路线,在我的情况下,这是login.js
,我可以调用setupController()
并切换应用程序控制器的hidesNavbar
和hidesFooter
属性。看起来像这样:
`// app/routes/login.js
import Route from '@ember/routing/route';
export default Route.extend({
setupController() {
this.controllerFor('application').set('hidesNavbar', true);
this.controllerFor('application').set('hidesFooter', true);
}
});`
现在,每当我们过渡到登录路由时,都会在应用程序控制器上设置hidesNavbar
和hidesFooter
属性,使app-navbar
中的isHidden
属性都app-footer
为真。