您是否可以预先加载相关数据,以便您的关系缓存在ember-data中?

时间:2014-01-05 13:35:08

标签: ember.js ember-data

我有一个简单的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();
    });
  }
});

1 个答案:

答案 0 :(得分:10)

让我们在这里分开一些事情

存储缓存

this.store.all('foo').clear();

只需断开内部all过滤器,直到修改/添加/删除foo记录,强制过滤器重新计算商店中的记录。我这样说是为了表明明确没有删除ED商店的记录。

示例(点击按钮,观看控制台,阅读有趣的动作代码)

http://emberjs.jsbin.com/OxIDiVU/103/edit

据说这不是被缓存的ajax,它是正在缓存的记录实例上的属性/关系(和记录)。

从商店中删除类型记录的正确方法是store.unloadAll('foo')

Promiselandia

我知道你已经熟悉了承诺,所以这部分可能毫无价值,但值得记录

异步关系非常酷,因为它们会为PromiseObject / PromiseArray返回belongsTo / hasManyPromiseObject / 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条建议

建立你自己的承诺,在你想要的时候解决,在所需的记录上使用Ember.RSVP.all(尊重他们可能已经或可能没有解决,因此异步)

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
});

http://emberjs.jsbin.com/OxIDiVU/106/edit