如何在ember数据中缓存查询结果

时间:2015-05-03 00:41:14

标签: javascript jquery caching ember.js ember-data

我想在ember-data中缓存查询结果。 (findQuery

说清楚:我不想缓存整个模型;只是什么模型是查询的结果。哪个地方适合这个?

我正在考虑在适配器中实现它并缓存AJAX调用的结果,但我不认为这是一个很好的解决方案,因为我不想覆盖已加载的,也许更新的和/或修改后的模型数据。

我不认为可以只返回ID列表,并操纵适配器这个简单用例的序列化程序似乎很麻烦!

实际上我不希望findQuery被调用特定类型的查询。就像findAll的行为一样。好的就像是queryShouldBeCached钩子。

有一个很好的解决方案吗?

2 个答案:

答案 0 :(得分:1)

我不是Ember专家,但我认为您可以使用纯JS解决方案来解决您的问题。

鉴于Ember Data查询返回Promises,例如return this.store.findAll('blog-post'); // => Promise,我们可以在具有更高阶函数的简单对象(返回函数的函数)中缓存promise。对象缓存可以替换为localStoragesessionStorageMap甚至WeakMap,但我正在使用对象缓存来简化操作。

您基本上要做的是更换以下电话:

return this.store.findAll('blog-post');

或多或少的东西:

return cachedStore.findAll('blog-post');

实际上,使用下面的解决方案可能看起来更像:

return cachedStore.call(this, 'findAll', 'blog-post');

因此,您将请求一次数据,并始终在后续调用中从缓存中返回。

让我告诉你实现的样子:

var cachedStore = (function () {
  // Your cache - in this case simple object literal
  var cache = {};

  // Actual method that will check cache for results before trying to query services
  return function (method) {
    var args = Array.prototype.slice.call(arguments, 1);
    var serializedArgs = JSON.stringify(args);

    if (!(serializedArgs in cache)) {
      cache[serializedArgs] = this.store[method].apply(this, args);
    }
    return cache[serializedArgs];
  };
}());

以下是一个示例用法:

// Fires a request
cachedStore.call(this, 'findAll', 'blog-post');
// Returns from cache
cachedStore.call(this, 'findAll', 'blog-post');
// Returns from cache
cachedStore.call(this, 'findAll', 'blog-post');

// Fires a request
cachedStore.call(this, 'findRecord', 'blog-post', 123);
// Returns from cache
cachedStore.call(this, 'findRecord', 'blog-post', 123);
// Returns from cache
cachedStore.call(this, 'findRecord', 'blog-post', 123);

这有什么用?

答案 1 :(得分:0)

当您根据参数触发请求时,Ember Data不知道这些参数是如何必然转化为模型的(也就是说它不知道您拥有所有具有某种关系的记录param1)。你可以自己缓存它,但是你仍然需要某种方式来知道商店中其他记录的那些记录。