8

我正在关注 Ember 2.3 的文档,似乎找不到任何非常基本的东西:如何访问主模板中路由模型钩子提供的值:application.hbs

路线/client.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) 访问,但不能被应用程序模板访问。

4

4 回答 4

4

以下是它的完成方式(除非 ember 在未来的版本中提出更好的方法):

路线/client.js

// ...
export default Ember.Route.extend({
    setupController() {
        this.controllerFor('application').set('navigation', ["nav1", "nav2"]);
    }
});

谢谢,伊万,回答!

于 2016-02-04T11:12:47.757 回答
2

如何访问主模板中路由模型钩子提供的值

默认情况下,在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()
});

现在您也可以访问该控制器模板中的导航。

于 2016-02-04T11:44:24.810 回答
0

我最近需要解决这个问题,我就是这样做的。

首先,这是我的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-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);
    }
});`

现在,每当我们转换到登录路由时,都会在应用程序控制器上设置hidesNavbarand属性,从而使and中的属性都为真。hidesFooterisHiddenapp-navbarapp-footer

于 2018-12-16T22:32:40.763 回答
0

我会这样解决这个问题。创建一个接受自定义参数的导航组件。

模板应用程序.hbs

{{custom-navigation url=apiURL user=user}}

现在在你的client.js

apiURL: 'navigations/client'

还有你的自定义组件custom-navigation.js

resolvedRouteNavs: function() {
   return DS.PromiseArray.create({
            promise: store.query(this.get('url'), { user? : userID?? });
   })
}.property('apiURL')

custom-navigation.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 钩子。

setupController: function(controller, model) {
        this._super(controller, model);

        controller.setProperties({
            nav: []
        });
于 2016-02-04T12:11:26.270 回答