Подтвердить что ты не робот

Как кэшировать результат запроса в данных ember

Я хочу кэшировать результат запроса в ember-data. (findQuery)

Чтобы было ясно: я не хочу кэшировать все модели; какие именно модели являются результатом запроса. Где подходящее место для этого?

Я думал о реализации этого в адаптере и кэшировал результат вызова AJAX, но я не думаю, что это хорошее решение, поскольку я не хочу переопределять загруженные и, возможно, более новые и/или измененные данные модели.

Я не думаю, что его можно просто вернуть список идентификаторов, а манипулировать адаптером и сериализатором для этого простого случая использования кажется беспорядочным!

На самом деле я не хочу, чтобы findQuery вызывался для определенных типов запросов. Как и поведение findAll. Ницца будет чем-то вроде крюка queryShouldBeCached.

Есть ли хорошее решение для этого?

4b9b3361

Ответ 1

Я не эксперт Ember, но думаю, что вы можете решить свою проблему с помощью чистого решения JS.

Данные запроса Ember Data возвращают Promises, например. return this.store.findAll('blog-post'); // => Promise, мы можем кэшировать promises в простом объекте с функциями более высокого порядка (функции, возвращающие функции). Кэш объектов можно заменить на localStorage, sessionStorage, Map или даже 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);

Помогает ли это в любом случае?

Ответ 2

Когда вы запускаете запрос на основе параметров, Ember Data не знает, как эти параметры обязательно переводятся в модели (иначе он не знает, что у вас есть все записи, которые имеют какое-то отношение param1). Вы можете кэшировать его самостоятельно, но тогда вам все равно потребуется какой-то способ узнать эти записи из других записей в вашем магазине.