您可以预加载相关数据,使您的关系缓存在ember数据中吗? [英] Can you pre-load related data such that your relationships are cached in ember-data?
问题描述
我有一个简单的hasMany / belongsTo关系看起来像这样
I have a simple hasMany/belongsTo relationship that looks like this
App.Foo = DS.Model.extend({
bar: belongsTo('bar', { async: true})
});
App.Bar = DS.Model.extend({
foos: hasMany('foo', { async: true})
});
我的路由代码中有一些情况会触发一个请求,当响应返回时,我访问相关的bar模型,我过滤掉/ etc
I have situations in my route code that fire off a request and when the response comes back I access the related "bar" model as I filter down / 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请求似乎已经缓存所有的条形对象,这是一个非问题)的问题。
The above doesn't work the first time around as foo.get('bar') is a promise. But this is only a problem the first time through (subsequent $.ajax requests seems to have all the bar objects cached so it's a non issue)
有什么奇怪的是,之前我甚至启动应用程序,我已经把init中的所有bar数据拉下来(如下所示)。那么,为什么在数据应该已经在本地存储的时候,ember数据甚至需要解决bar的承诺?
What's strange is that before I even boot the app I've already pulled down all the bar data in the init (shown below). So why does ember-data even need to resolve the promise for "bar" when technically that data should already be in the store locally?
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();
});
}
});
推荐答案
我们在这里分开一些东西
Let's separate a few things here
this.store.all('foo').clear();
只需打破内部所有
过滤器,直到 foo
记录被修改/添加/删除,强制过滤器重新计算商店中的记录。我说这是为了表明明确的是没有从ED的商店中删除记录。
just breaks the internal all
filter until a foo
record is modified/added/removed forcing the filter to recalculate for the record in the store. I say this to show that clear isn't removing the records from ED's store.
示例(点击按钮,观看控制台,阅读有趣的动作代码)
http://emberjs.jsbin。 com / OxIDiVU / 103 / edit
据说这不是被缓存的ajax,它是记录实例上的属性/关系缓存(和记录)。
That being said it isn't the ajax that's being cached, it's the property/relationship on the record instance that's being cached (and the record).
从商店中删除类型记录的正确方法是 store.unloadAll('foo')
The proper way to remove the records of a type from the store is store.unloadAll('foo')
我知道你已经熟悉承诺了,所以这部分可能是毫无价值的,但值得记录的
I know you're already familiar with promises, so this part may be worthless, but, worth documenting
异步关系真的很酷,因为他们返回 PromiseObject
/ PromiseArray
for belongsTo
/ hasMany
。 PromiseObject
/ PromiseArray
extends ObjectProxy
/ ArrayProxy
(这些与 ObjectController
/ ArrayController
extends)相同。这实际上是给予代理获取/设置下面的模型的能力的 PromiseObject
/ 。在这种情况下,承诺的设置/获得不会承诺,直到承诺得到解决(它不会崩溃,只是返回未定义)。 *注意事项,方法不存在的承诺,所以你不能调用保存的承诺,并期望它的工作。
The async relationships are really cool because they return PromiseObject
/PromiseArray
for belongsTo
/hasMany
. The PromiseObject
/PromiseArray
extend ObjectProxy
/ArrayProxy
(these are the same things that ObjectController
/ArrayController
extend). This essentially gives the PromiseObject
/PromiseArray
the ability to proxy getting/setting of properties to the model underneath. In this case the setting/getting happens on the promise doesn't "work" until the promise has been resolved (it won't crash, just return undefined). *Caveat, methods don't exist on the promise, so you can't call save on the promise and expect it to work.
var foo = this.store.find('foo', 1);
var bar = foo.get('bar'); // PromiseObject
bar.get('name'); // undefined
稍后,栏已解决,栏仍然是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条建议
In your case I have 3 recommendations
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
很多时候使用异步对象/属性,在模型钩子期间没有解决(阻止承诺和等待直到解决)一个好的伎俩是设置一个占位符对象等。
A lot of times with async objects/properties that aren't resolved during the model hook (which blocks on promises and wait's until they are resolved) a good trick is to set a placeholder object etc.
var items = [];
controller.set('model', items);
// promise from above
promise.then(function(records){
items.pushObjects(records.toArray()); // toArray may or may not apply
});
http://emberjs.jsbin.com/OxIDiVU/106/edit
这篇关于您可以预加载相关数据,使您的关系缓存在ember数据中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!