强制版信息:
"DEBUG: Ember : 1.6.0-beta.1+canary.ffa2c83c"
"DEBUG: Ember Data : 1.0.0-beta.7+canary.d55198c2"
"DEBUG: Handlebars : 1.3.0"
"DEBUG: jQuery : 2.1.0"
我有像这样设置的余烬数据模型
App.User = DS.model.extend({
username: DS.attr(),
sites: DS.hasMany('site', {async:true})
});
这样的路线设置如下:
App.SitesRoute = Ember.Route.extend({
setupController: function (controller, model) {
this.controllerFor('auth').get('model.sites').then(function(sites){
controller.set('model', sites);
});
});
});
auth控制器为我提供了当前登录的用户,我希望站点路由仅显示与当前登录用户相关的站点。
然而,这不起作用并抛出错误
"Error while loading route: App.SitesRoute<.setupController"
有趣的是,如果我在那里抛出一个断点,这个setupcontroller挂钩实际上是有效的,没有错误发生,数据加载到用户界面。
这让我相信这里的承诺加载存在问题,但我无法解决原因。我会想到,当'model.sites'的承诺完成后,控制器模型会被设置,而这又会填充内容和我的ui。但事实似乎并非如此。
有什么想法吗?我在这里做错了什么?
修改1
这是一种具有类似结果的变体。如果我在路由的模型钩子中的return语句上放置一个断点,它就可以工作。否则它不会
App.SitesRoute = Ember.Route.extend({
model: function () {
return this.controllerFor('auth').get('model.sites');
},
setupController: function (controller, model) {
controller.set('model', model);
}
});
修改2
好的,这是使这段代码有效的东西。但在我看来,与docs相反的是:
“如果数据是异步可用的,您可以返回 来自模型钩子的承诺,Ember将等到那个承诺 在渲染模板之前解决。“
我原以为调用self.controllerFor('auth')。get('sites')是一个承诺,如果'sites'关系被标记'asyc:true'我错了吗?
所以我可以这样做并且它有效,我想这有点模拟断点:
App.SitesRoute = Ember.Route.extend({
model: function() {
var self = this;
return new Ember.RSVP.Promise(function(resolve) {
Ember.run.later(function() {
resolve(self.controllerFor('auth').get('sites'));
}, 3000);
});
},
setupController: function(controller,model) {
controller.set('content', model);
}
});
编辑3
好的,我找到了一些有用的东西,我现在也会参与其中,但我仍然对不了解正在发生的事情或原因感到不满。我忽略了一些事情,即我正在使用ember-data-django-rest-adapter我无法判断这是否是导致问题的原因,尽管有几个小时的调试ember和适配器的内部结构。
这里没有进一步的麻烦是最终工作:
App.SitesRoute = Ember.Route.extend({
setupController: function(controller,model) {
this.controllerFor('auth').get('content').then(function (user) {
user.get('sites').then(function (sites) {
controller.set('content', sites);
});
});
}
});
如果对其他方法不起作用的原因有任何见解,将不胜感激。
答案 0 :(得分:1)
我要做的是让所有控制器都知道当前用户是将currentUserController注入到ember初始化程序中的所有控制器中。然后,你可以通过像this.get('currentUser')那样访问控制器中的任何一点来获取currentUser。]
在你的情况下,我会尝试这个,看看它是否有效:
model: function() {
return this.controllerFor('auth').get('sites');
},
setupController: function(controller,model) {
model.then(function(response) {
controller.set('content', response);
}
}
答案 1 :(得分:1)
我发现当我有一个使用async: true
的模型关系时,我可以期待当我得到那个关系时,结果是一个承诺,例如:
var stuff = model.get('relatedCollection');
var actualStuff;
if (typeof stuff.then === 'function') {
stuff.then(function (collection) {
actualStuff = collection;
});
} else {
actualStuff = stuff;
}
以上是伪代码,用于说明当您定义模型依赖关系时使用aysc: true
时,您很可能会在get
相关集合时看到承诺。
我注意到,当承诺得到解决时,即使您设置了断点,当您get
相关集合时,您可能会看到实际的集合而不是承诺。
因此,当我使用aysc: true
时,我通常会使用分支代码来首先检查结果是否可以typeof thing.then === 'function'
如果是这样,我会将指定的值视为承诺;并且在解析promise之后使用thenable语法来获取模型的实际集合。