4

按照Ember上的示例在我的 ArrayController 定义中设置 itemController 会导致阻塞错误消息:

TypeError: Cannot call method 'lookup' of null

JSFiddle:http: //jsfiddle.net/jgillick/M4BVV/

// Addresses array controller
App.AddressesController = Ember.ArrayController.extend({
    itemController: 'address'
});

// Address object controller
App.AddressController = Ember.ObjectController.extend({
    city: function(){
        return "San Francisco";
    }.property()
});

我发现解决这个问题的唯一方法是......

1)在#each处理程序(jsfiddle)中传递itemController:

{{#each addresses itemController="address"}}
    <li>{{line1}}, {{city}}</li>
{{/each}}

...或者...

2) 向 ArrayController ( jsfiddle )添加容器属性:

var addresses = App.AddressesController.create({
    container: indexController.get('container'),
    content: [
        App.Address.create({'line1': '700 Hansen Wy'}),
        App.Address.create({'line1': '900 Hansen Wy'})
    ]
});

这两种解决方案都让人觉得很笨拙而且非常错误。在 ArrayController 本身中设置 itemController 我做错了什么?

4

4 回答 4

6

The itemController from the controller and the each view, don't have relation. Although that do the same thing: wraps an object in a specified controller.

Your first implementation throws Cannot call method 'lookup' of null, because the container instance of the AddressesController is null. The container is setup when you create a controller by other container. This is abstracted for you, if you use:

this.controllerFor('addresses')

instead of

 App.AddressesController.create ...

So this work http://jsfiddle.net/marciojunior/GRaa5/

1) Pass itemController in the #each handler

Like I said before, itemController from controller, and each helper, don't have relation. So you can mix him.

{{#each addresses itemController="address"}}
    <li>{{line1}}, {{city}}</li>
{{/each}}

See this in action http://jsfiddle.net/marciojunior/spA9Q/

2) Add a container property to the ArrayController

This work because of the my previous explanation,

because the container instance of the AddressesController is null

Finishing the @colymba example works, because before of the setupController:

setupController: function(controller, model){
    controller.set('content', model);
}

ember provide a controller in that hook using the controllerFor, then the container is present in the generated controller too.

于 2013-08-13T01:55:35.933 回答
2

看着小提琴,这并不是最好的方法。快速清理代码,我得到了这个小提琴:http: //jsfiddle.net/colymba/kV8LM/

我所做的是,添加一个路由AddressesRoute,它IndexRoute重定向到:

App.Router.map(function() { 
  this.route("addresses");
});

App.IndexRoute = Ember.Route.extend({
    redirect: function() {
        this.transitionTo('addresses');
    }
});


App.AddressesRoute = Ember.Route.extend({
    model: function(params){
        return [
            App.Address.create({'line1': '700 Hansen Wy'}),
            App.Address.create({'line1': '900 Hansen Wy'})
        ];
    },
    setupController: function(controller, model){
        controller.set('content', model);
    }
});

使用命名约定有助于AddressesRouteEmber 自动实例化控制器和视图。

相应地更改视图,将其名称更改为addresses并更新{{#each}}to 循环content

<script type="text/x-handlebars" data-template-name="addresses">
     <h2>Index Content:</h2>
    <p>
        Length: {{content.length}}
    </p>
    <ul>
    {{#each addresses in controller}}
        <li>{{line1}}, {{city}}</li>
    {{/each}}
    </ul>
</script>

{{#each}}循环也可以直接编写,{{#each controller}}因为它会默认查找content或查找model。在这两种情况下,都controller告诉 View 它应该访问它的 Controller 以查找{{#each}}循环的内容,否则itemController不使用 (因为它在 View 上不存在)。(这与@intuitivepixel 所说的有关)

模型和控制器与您的相同:

App.Address = Ember.Object.extend();

App.AddressController = Ember.ObjectController.extend({
    city: function(){
        return "San Francisco";
    }.property()
});

App.AddressesController = Ember.ArrayController.extend({
    itemController: 'address'
});

App.IndexController = Ember.ObjectController.extend();
于 2013-08-12T20:04:24.160 回答
1

首先,该代码对我来说似乎有点奇怪,但无论如何,这里的事情是您正在路由器中创建一个新的“AddressesController”实例,您需要将其更改为如下内容:

App.IndexRoute = Ember.Route.extend({
  setupController: function(indexController) {
    this.controllerFor('addresses').set('content', [App.Address.create({'line1': '700 Hansen Wy'}), App.Address.create({'line1': '900 Hansen Wy'})]);
    indexController.set('addresses', this.controllerFor('addresses'));
  }
})
于 2013-08-12T19:33:27.357 回答
0

我最初在尝试在itemController内部实例化时遇到了同样的错误ArrayController。虽然,我的错误是破坏 init 方法的结果:

App.UsersController = Ember.ArrayController.extend({
    init: function() {
        console.log('i am USERS CONTROLLER');
    },
    itemController: 'user',
});

我通过将默认行为恢复到 init 方法来修复:

App.UsersController = Ember.ArrayController.extend({
    init: function() {
        this._super();
        console.log('i am USERS CONTROLLER');
    },
    itemController: 'user',
});
于 2014-06-26T04:52:40.800 回答