0

我有一个小的 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,不起作用。从概念上讲,据我了解,这甚至应该是正确的方法,因为在其他任何地方我都在路由中定义控制器的模式数据。

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

4

2 回答 2

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/子项

发生了什么变化:

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

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

于 2013-09-02T14:19:55.273 回答
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/

于 2013-08-30T16:12:16.833 回答