【问题标题】:How to correctly access a parent controllers data (model) in nested resources?如何正确访问嵌套资源中的父控制器数据(模型)?
【发布时间】:2013-08-30 10:03:03
【问题描述】:

我有一个小的 EmberJS 应用程序来测试热门的嵌套资源。有时访问父路由/控制器数据有效,有时则无效。 这很可能是由于我对 EmberJS 如何发挥其魔力的疏忽。

这是应用程序:

window.App = Ember.Application.create();

  App.Router.map(function() {
    this.resource('items', function() {
      this.resource('item', {path: ':item_id'}, function() {
        this.resource('subitems');
      });
    });
  });

  App.ApplicationController = Ember.Controller.extend({
    model: {
      items: [
        {
          id: 1,
          name: 'One',
          subitems: [
            {
              id: 1,
              name: 'One One'
            }, {
              id: 2,
              name: 'One Two'
            }
          ]
        }, {
          id: 2,
          name: 'Two',
          subitems: [
            {
              id: 3,
              name: 'Two One'
            }, {
              id: 4,
              name: 'Two Two'
            }
          ]
        }
      ]
    }
  });

  App.ItemsRoute = Ember.Route.extend({
    model: function() {
      return this.controllerFor('Application').get('model.items')
    }
  });

  App.ItemRoute = Ember.Route.extend({
    model: function(params) {
      var items = this.controllerFor('Items').get('model')
      var item  = items.filterBy('id', parseInt(params.item_id))[0]
      return item
    }
  });

  App.SubitemsRoute = Ember.Route.extend({
    model: function(params) {
      var item = this.controllerFor('Item').get('model')
      var subitems = item.get('subitems')
      return subitems
    }
  });

http://jsfiddle.net/maxigs/cCawE/

这是我的问题:

导航到 items/1/subitems 会引发错误:

Error while loading route: TypeError {} ember.js:382
Uncaught TypeError: Cannot call method 'get' of undefined test:67

我并没有真正明白,因为显然 ItemController 正确加载了它的数据(它显示出来了),并且相同的构造也适用于 ItemsRoute 以获取它的数据。

由于我无法访问父路由参数 (item_id),因此我没有其他方法可以重新获取数据,即使直接从 ApplicationController 访问数据也可以正常工作。

为什么我在控制器中定义了根数据而不是路由?

将模型定义从 ApplicationController 移动到 ApplicationRoute,不起作用。 从概念上讲,据我了解,这甚至应该是正确的方法,因为在其他任何地方我都在路由中定义控制器的模式数据。

还是应该通过控制器需要更好地完成整个事情?据我了解,需要更多的是仅访问控制器(或其视图)中的额外数据,但路由器的工作是提供模型。

【问题讨论】:

    标签: ember.js nested-resources


    【解决方案1】:

    1.导航到 items/1/subitems 会引发错误:

    您的模型只是一个 javascript 对象,因此没有获取数据的方法。您只需执行 item.subitems 即可访问子项。

    controllerFor() 的参数也应该是小写的。

    例如:

    this.controllerFor('application')
    

    2。为什么我在控制器中定义了根数据而不是路由?

    您可以通过setupController 方法中的路由设置模型。

    App.ApplicationRoute = Ember.Route.extend({
      setupController: function(controller) {
        controller.set('model', { ... });
      }
    });
    

    http://jsfiddle.net/Y9kZP/

    【讨论】:

    • 您的解决方案仍然存在与我相同的 1. 问题。直接导航到子项不起作用,抛出同样的错误:fiddle.jshell.net/Y9kZP/show/#/items/1/subitems.
    • 有趣的是,我发现了一个有时有效的解决方案。只需在 subitems 路由器中将 controllerFor('item').get('model.subitems') 更改为 modelFor('item').get('subitems') 即可。即使将初始数据移动到 ApplicationRouter 也可以。至少此更改使其可以在我的本地版本的应用程序中运行(除了模型名称外相同)。但是在 jsfiddle 中它仍然会引发错误?!
    【解决方案2】:

    经过更多的摆弄,这里是问题中示例的工作版本:

    window.App = Ember.Application.create();
    
    App.Router.map(function() {
        this.resource('items', function() {
            this.resource('item', {path: ':item_id'}, function() {
                this.resource('subitems');
            });
        });
    });
    
    App.ApplicationRoute = Ember.Route.extend({
        model: function() {
            return Ember.Object.create({
                items: [
                    Ember.Object.create({
                        id: 1,
                        name: 'One',
                        subitems: [
                            {
                                id: 1,
                                name: 'One One'
                            }, {
                                id: 2,
                                name: 'One Two'
                            }
                        ]
                    }), Ember.Object.create({
                        id: 2,
                        name: 'Two',
                        subitems: [
                            {
                                id: 3,
                                name: 'Two One'
                            }, {
                                id: 4,
                                name: 'Two Two'
                            }
                        ]
                    })
                ]
            })
        }
    });
    
    App.ItemsRoute = Ember.Route.extend({
        model: function() {
             return this.modelFor('application').get('items')
        }
    });
    
    App.ItemRoute = Ember.Route.extend({
        model: function(params) {
            return this.modelFor('items').findProperty('id', parseInt(params.item_id))
        }
    });
    
    App.SubitemsRoute = Ember.Route.extend({
        model: function(params) {
            return this.modelFor('item').get('subitems')
        }
    });
    

    http://jsfiddle.net/maxigs/cCawE/6/ 和子项目的深层链接(以前不起作用)http://fiddle.jshell.net/maxigs/cCawE/6/show/#/items/2/subitems

    发生了什么变化:

    1. 根模型数据移入 ApplicationRoute
    2. root-model 移动到 ember 对象中,子对象也是它们自己的 ember 对象(因此调用 get('subitems') 和其他 ember 魔术)
    3. 把所有的controllerFor('xxx').get('model')都改成了modelFor('xxx')(小写!),大概除了一致性之外没什么影响

    我仍然不确定这是否是现在做我在这里所做的事情的“余烬方式”,但它是一致的并且完全可以按需要工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      相关资源
      最近更新 更多