如何从 Ember 应用程序模板中的路由访问数据



我正在关注 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-navbarapp-footer 都是知道如何使用 isHidden 属性使自己可见或不可见的组件。切换可见性有不同的方法,但为了简洁起见,让我们将任一组件的内容包装在条件块中,如下所示:

`<!-- app-navbar and app-footer -->
{{#unless isHidden}} 
     <!-- component HTML here --> 
{{/unless}}
`

现在,从我不想看到app-navbarapp-footer的路线,在我的情况下,这是login.js,我可以调用setupController()并切换应用程序控制器的hidesNavbarhidesFooter属性。看起来像这样:

`// 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);
    }
});`

现在,每当我们过渡到登录路由时,都会在应用程序控制器上设置hidesNavbarhidesFooter属性,使app-navbar中的isHidden属性都app-footer为真。

最新更新