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

2024-04-19

我有一个简单的 hasMany/belongsTo 关系,如下所示

App.Foo = DS.Model.extend({
  bar: belongsTo('bar', { async: true})
});
App.Bar = DS.Model.extend({
  foos: hasMany('foo', { async: true})
});

我的路由代码中存在触发请求的情况,当响应返回时,我在过滤/等时访问相关的“bar”模型

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

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

存储缓存

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

只是破坏了内部all过滤直至foo记录被修改/添加/删除,迫使过滤器重新计算存储中的记录。我这样说是为了表明clear 并没有从 ED 的存储中删除记录。

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

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

也就是说,被缓存的不是 ajax,而是被缓存的记录实例(和记录)上的属性/关系。

从存储中删除某种类型的记录的正确方法是store.unloadAll('foo')

普罗米塞兰迪亚

我知道您已经熟悉 Promise,所以这部分可能毫无价值,但是值得记录

异步关系真的很酷,因为它们会返回PromiseObject/PromiseArray for belongsTo/hasMany. The PromiseObject/PromiseArray extend ObjectProxy/ArrayProxy(这些是相同的事情ObjectController/ArrayController延长)。这本质上给出了PromiseObject/PromiseArray代理获取/设置下面模型的属性的能力。在这种情况下,在承诺上发生的设置/获取在承诺得到解决之前不会“工作”(它不会崩溃,只是返回未定义)。 *警告,承诺中不存在方法,因此您不能对承诺调用 save 并期望它起作用。

前任。使用你的模型。

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

saving

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 http://emberjs.jsbin.com/OxIDiVU/104/edit

异步属性

很多时候,对于在模型挂钩期间未解析的异步对象/属性(它会阻止 Promise 并等待它们被解析),一个好技巧是设置占位符对象等。

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 http://emberjs.jsbin.com/OxIDiVU/106/edit

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

您可以预加载相关数据,以便将您的关系缓存在 ember-data 中吗? 的相关文章

随机推荐