Javascript 如何从Ember应用程序模板中的路由访问数据?
我正在关注Ember 2.3的文档,似乎找不到任何非常基本的东西:如何在主模板中访问路由模型挂钩提供的值:Javascript 如何从Ember应用程序模板中的路由访问数据?,javascript,ember.js,ember.js-2,Javascript,Ember.js,Ember.js 2,我正在关注Ember 2.3的文档,似乎找不到任何非常基本的东西:如何在主模板中访问路由模型挂钩提供的值:application.hbs routes/client.js 模板/application.hbs {{{#每个导航为| navItem}} {{{#链接到navItem.link}{{navItem.title}}{{/link到}} {{/每个}} {{outlet}} 现在,导航对象可以访问路由模板(client.hbs),但不能访问应用程序模板。以下是导航对象的操作方式(除非
application.hbs
routes/client.js
模板/application.hbs
{{{#每个导航为| navItem}}
{{{#链接到navItem.link}{{navItem.title}}{{/link到}}
{{/每个}}
{{outlet}}
现在,导航对象可以访问路由模板(client.hbs
),但不能访问应用程序模板。以下是导航对象的操作方式(除非ember在未来的版本中提出了更好的方法):
routes/client.js
伊万,谢谢你的回答
如何访问主模板中路由的模型钩子提供的值
默认情况下,在路由的钩子内,Ember将返回从路由的模型钩子返回的承诺的解析值
这意味着您可以使用模板中的属性model
访问model.navigation
:
<nav>
{{#each model.navigation as |navItem|}}
<li>{{#link-to navItem.link}} {{navItem.title}} {{/link-to}}</li>
{{/each}}
</nav>
这意味着您现在可以在模板中使用导航
而不是model.navigation
。另一种方法是在控制器内部为model
属性添加:
export default Ember.Controller.extend({
navigation: Ember.computed.alias('model.navigation')
// ... rest of the code
})
这将允许您使用navigation
而不是model.navigation
但是,如果您希望在应用程序中具有某种全局导航,更好的方法是使用一个可以插入到任何需要导航的控制器中的。比如:
// 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
现在在client.js中
以及您的自定义组件custom-navigation.js
和custom-navigation.hbs
如果将静态数组作为导航处理
然后,不需要解析,只需输出绑定的数组,这对于每个路由都是不同的
client.js
some-different-place.js
实际上,模型钩子应该包含从服务器检索的数据。否则,请使用setupcontrollerhook
setupController: function(controller, model) {
this._super(controller, model);
controller.setProperties({
nav: []
});
我最近需要解决这个问题,我就是这样做的
首先,这是我的应用程序.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
的路径,在我的例子中,这是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
和app footer
中设置ishiden
属性。首先,您应该使用{{#each model.navigation…}}在模板中。其次,每个路由都对应于其模板。在您的情况下,您需要应用程序路由来显示应用程序hbs中模型的数据。这正是我不感兴趣的,@kristjan。我有一个(非常常见的)在这种情况下,我需要一个常规的路由来提供要在父模板(application.hbs)内部访问的数据。例如,活动导航列表。@Slavic每个模板都有自己的路线。约定优先于配置,但如果您想在应用程序路线中显示导航模型,为什么不为应用程序路线返回多个模型?@Craicerjack假设我想按照ember的方式,如何解决此问题手边?问题仍然存在:application.hbs甚至没有自己的路由器,即使它有,它的路由器也不会知道数据,因为根据问题的定义,数据是特定于子例程的。你能提供一些额外的文本吗?你想实现什么?也许有更好的方法来解决你的问题,你也可以r从错误的角度看它。因为你目前所做的对我来说没有任何意义。焦点不是控制方法的正确位置,但是,是的-我同意这不是最好的位置我不关心使用另一个名称访问数据。对我来说model.navigation完全可以。任务是抓住在数据处。@Slavic好的,我明白我是如何误解你的,我更正了我的回答。我还添加了一个建议,说明如何在必要时实施更多的全球导航。不幸的是,一项服务似乎并没有解决眼前的问题。它源于这样一个事实,即每个控制器对导航都有发言权(例如,将导航项标记为活动项,但不仅仅是此项)。目前我倾向于使用setupController解决方案,尽管我还不知道它是否能解决我所有的导航问题,但它确实是一个解决问题的解决方案,具体来说。我对您投了赞成票。
export default Ember.Controller.extend({
navigation: Ember.service.inject()
});
{{custom-navigation url=apiURL user=user}}
apiURL: 'navigations/client'
resolvedRouteNavs: function() {
return DS.PromiseArray.create({
promise: store.query(this.get('url'), { user? : userID?? });
})
}.property('apiURL')
{{#each resolvedRouteNavs as |navItem|}}
{{navItem.name}}
{{/each}}
navs: [{ name: '1', route: 'foo'}, { name: '2', route: 'bar' }]
navs: [{ name: 'blah', route: 'foo.bar'}, { name: 'meh', route: 'bar.foo' }]
setupController: function(controller, model) {
this._super(controller, model);
controller.setProperties({
nav: []
});
` <!-- 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 and app-footer -->
{{#unless isHidden}}
<!-- component HTML here -->
{{/unless}}
`
`// 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);
}
});`