您可以预加载相关数据,使您的关系缓存在ember数据中吗? [英] Can you pre-load related data such that your relationships are cached in ember-data?

查看:105
本文介绍了您可以预加载相关数据,使您的关系缓存在ember数据中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆