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

时间:2016-02-03 16:36:22

标签: javascript ember.js ember-2.0.0

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

路由/ client.js

// ...
export default Ember.Route.extend({
    model() {
        return {
            navigation: [
                {
                    title: "Projects",
                    link: "projects"
                },
                {
                    title: "My Specifications",
                    link: "specs"
                }
            ]
        }
    }
});

模板/ application.hbs

<nav>
   {{#each navigation as |navItem|}}
      <li>{{#link-to navItem.link}} {{navItem.title}} {{/link-to}}</li>
   {{/each}}
</nav>
{{outlet}}

现在,导航对象可以访问路径的模板(client.hbs),但不能访问应用程序模板。

4 个答案:

答案 0 :(得分:4)

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

路由/ client.js

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

谢谢,伊万,答案!

答案 1 :(得分:2)

  

如何访问主模板

中路由模型钩子提供的值

默认情况下,在路由的setupController挂钩内,Ember将set the property model on your controller指向从路由的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属性添加alias

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()
});

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

答案 2 :(得分:0)

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

模板 application.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}}

如果你正在处理静态数组作为导航

然后不需要解析,只需要输出绑定数组,每个路由都不同。

client.js

navs: [{ name: '1', route: 'foo'}, { name: '2', route: 'bar' }]

一些-不同-place.js

navs: [{ name: 'blah', route: 'foo.bar'}, { name: 'meh', route: 'bar.foo' }]

真正的模型钩子应该包含从服务器检索的数据。否则使用setupController hook。

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

        controller.setProperties({
            nav: []
        });

答案 3 :(得分: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-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属性都会在应用程序控制器上进行设置,从而使isHidden和{{1 }}都是正确的。