按照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()
});
我找到解决此问题的唯一方法是......
{{#each addresses itemController="address"}}
<li>{{line1}}, {{city}}</li>
{{/each}}
...或...
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我做错了什么?
答案 0 :(得分:6)
来自控制器的itemController
和每个视图没有关系。
虽然它做同样的事情:在指定的控制器中包装一个对象。
您的第一个实现会抛出Cannot call method 'lookup' of null
,因为container
的{{1}}实例为null。当您通过其他容器创建控制器时,将设置容器。如果你使用:
AddressesController
而不是
this.controllerFor('addresses')
所以这项工作http://jsfiddle.net/marciojunior/GRaa5/
1)在#each处理程序
中传递itemController
就像我之前说过的那样,来自控制器的 App.AddressesController.create ...
和每个助手都没有关系。所以你可以混合他。
itemController
在行动http://jsfiddle.net/marciojunior/spA9Q/
中查看此内容2)将一个容器属性添加到ArrayController
这项工作是因为我之前的解释,
因为
{{#each addresses itemController="address"}} <li>{{line1}}, {{city}}</li> {{/each}}
的{{1}}实例为空
完成@colymba示例有效,因为在setupController之前:
container
ember使用AddressesController
在该钩子中提供控制器,然后容器也存在于生成的控制器中。
答案 1 :(得分: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);
}
});
使用命名约定有助于AddressesRoute
,Ember自动实例化Controller和View。
相应地更改视图,将其名称更改为addresses
并更新{{#each}}
以循环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它应该访问其控制器以查找{{#each}}
循环的内容,否则itemController
不会被使用(因为它没有&#39} ; t存在于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();
答案 2 :(得分: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'));
}
})
答案 3 :(得分: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',
});