如何在嵌套资源中正确访问父控制器数据(模型)?

时间:2013-08-30 10:03:04

标签: ember.js nested-resources

我有一个小的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来获取它的数据。

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

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

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

或者应该通过控制器需求-api更好地完成整个事情?据我所知,只需要访问控制器(或其视图)中的额外数据,但路由器的工作就是提供模型。

2 个答案:

答案 0 :(得分:0)

<强> 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 :(得分:0)

在这里更多的摆弄之后是问题中示例的工作版本:

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 magic工作)
  3. 将所有controllerFor('xxx')。get('model')更改为modelFor('xxx')(小写!),除了一致性之外可能没有任何影响
  4. 我仍然不确定这是否是现在做“我所拥有的”的“余烬方式”,但它的一致性和完全按照需要运作。