Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从Ember应用程序模板中的路由访问数据?_Javascript_Ember.js_Ember.js 2 - Fatal编程技术网

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

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),但不能访问应用程序模板。以下是导航对象的操作方式(除非

我正在关注Ember 2.3的文档,似乎找不到任何非常基本的东西:如何在主模板中访问路由模型挂钩提供的值:
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);
        }
    });`