我有一个简单的hasMany / belongsTo关系,看起来像这样
App.Foo = DS.Model.extend({
bar: belongsTo('bar', { async: true})
});
App.Bar = DS.Model.extend({
foos: hasMany('foo', { async: true})
});
我的路线代码中的情况触发了请求,当响应返回时,我访问相关的“bar”模型,因为我过滤了/ etc
this.store.all('foo').clear();
var fooz = self.store.all('foo'); //new code
return this.store.find('foo').then(function(response) {
var filtered = response.filter(function(foo) {
return foo.get('bar').get('name') === 'bazz';
});
//other code that would normally be executed top-down
//including side-effect stuff like this
//self.store.createRecord('foo', someHash);
return fooz; //new code
});
上面的第一次不起作用,因为foo.get('bar')是一个承诺。但这只是第一次遇到的问题(随后的$ .ajax请求似乎已经缓存了所有bar对象,所以这不是问题)
奇怪的是,在我启动应用程序之前,我已经删除了init中的所有条形数据(如下所示)。那么为什么在技术上数据应该已经在本地存储的情况下,为什么ember-data甚至需要解决“bar”的承诺呢?
App.initializer({
name: 'bootstrap',
initialize: function() {
App.deferReadiness();
var store = App.__container__.lookup("store:main");
var bars = store.find('bar');
var configurations = store.find('configuration');
Ember.RSVP.all([bars, configurations]).then(results) {
App.advanceReadiness();
});
}
});
答案 0 :(得分:10)
让我们在这里分开一些事情
this.store.all('foo').clear();
只需断开内部all
过滤器,直到修改/添加/删除foo
记录,强制过滤器重新计算商店中的记录。我这样说是为了表明明确没有删除ED商店的记录。
示例(点击按钮,观看控制台,阅读有趣的动作代码)
http://emberjs.jsbin.com/OxIDiVU/103/edit
据说这不是被缓存的ajax,它是正在缓存的记录实例上的属性/关系(和记录)。
从商店中删除类型记录的正确方法是store.unloadAll('foo')
我知道你已经熟悉了承诺,所以这部分可能毫无价值,但值得记录
异步关系非常酷,因为它们会为PromiseObject
/ PromiseArray
返回belongsTo
/ hasMany
。 PromiseObject
/ PromiseArray
扩展ObjectProxy
/ ArrayProxy
(这些与ObjectController
/ ArrayController
扩展的内容相同。这基本上使PromiseObject
/ PromiseArray
能够代理获取/设置属性到下面的模型。在这种情况下,承诺上的设置/获取不会“工作”,直到承诺得到解决(它不会崩溃,只返回undefined)。 *警告,承诺中不存在方法,因此您无法调用保存承诺并期望它能够正常工作。
var foo = this.store.find('foo', 1);
var bar = foo.get('bar'); // PromiseObject
bar.get('name'); // undefined
以后,bar已经解决,bar仍然是PromiseObject
bar.get('name'); // billy
foo将继续返回PromiseObject
var bar2 = foo.get('bar'); // PromiseObject
bar2.get('name'); // billy
<强>保存强>
bar.save(); // Boom no workey
bar.then(function(realBar){
realBar.save(); // workey
});
在你的情况下,我有3条建议
var self = this;
var promise = new Ember.RSVP.Promise(function(resolve, reject){
self.store.find('foo').then(function(foos) {
Em.RSVP.all(foos.getEach('bar')).then(function(bars){
var filtered = bars.filterBy('name', 'bazz');
resolve(filtered);
});
});
});
return promise;
http://emberjs.jsbin.com/OxIDiVU/104/edit
很多时候,在模型钩子期间没有解析的异步对象/属性(它们在promises上等待并等待它们被解析)一个好方法就是设置一个占位符对象等。
var items = [];
controller.set('model', items);
// promise from above
promise.then(function(records){
items.pushObjects(records.toArray()); // toArray may or may not apply
});