在Ember中,控制器何时可以访问模型?
下面是一个简单的Ember应用程序,它包含一个静态模型和一个试图访问init
模型的控制器。您会注意到,在init
上,模型title
属性为undefined
。但是,setTimeout说明稍后可以访问model
。
我的印象是,在模型准备好之前,Ember不会启动控制器。它是否正确? Ember文档(http://emberjs.com/guides/routing/specifying-a-routes-model/)表示在实例化控制器时,即使异步加载模型也可用。
http://jsfiddle.net/vu263uwq/1/
App = Ember.Application.create({});
App.IndexRoute = Ember.Route.extend({
model: function() {
return posts[0];
}
});
App.IndexController = Ember.ObjectController.extend({
alertTitle: function() {
var that = this;
jQuery(".output").append("1. "+this.get("title")+"<br />"); //Returns "undefined"
setTimeout(function() {
jQuery(".output").append("2. "+that.get("title")); //Returns the correct title
}, 1000);
}.on("init")
});
var posts = [
{
id: 1,
title: "First title",
body: "Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam quis risus eget urna mollis ornare vel eu leo. Cras justo odio, dapibus ac facilisis in, egestas eget quam."
},{
id: 2,
title: "Second title",
body: "Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum."
}
];
答案 0 :(得分:2)
你的印象实际上是错误的。 setupController挂钩是您在控制器上设置任何属性的位置,包括模型。实际上,默认情况下,所有setupController
都会在控制器上设置模型。这就是为什么如果您覆盖挂钩并仍需要model
设置,则必须明确设置模型或拨打this._super(controller, model)
。
注意setupController的签名:
setupController: function(controller, model)
为了使其工作,控制器必须已经由Ember设置模型的点进行实例化。在控制器实例化期间触发Init。因此,在init
设置
model
对于模型的异步提取,如果模型挂钩返回一个promise,Ember将阻塞,直到可以将完成的promise传递给setupController
函数,以便将模型分配给promise#s实现而非承诺本身。它可以让你避免像:
setupController: function(controller, model){
var self = this;
makeAsyncCallReturningPromise().then(function(result){
self._super(controller, result);
}
}
基本上可以完成同样的事情