2015-05-03 2 views
35

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

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

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

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

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

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

+0

Где вы используете кеш, то есть на конкретном маршруте, и кеш будет очищен при повторном запуске запроса или есть переход от маршрута? – aceofspades

+0

есть переход от маршрута.Вариант использования заключается в том, что я показываю список результатов поиска, пользователь нажимает на результат и переходит к странице подробностей. если он вернется, я не хочу повторно запускать поиск, который стоит почти 5 секунд. – Lux

+1

Я перехватываю крючки 'setupController' и' deactivate' маршрута, где я беру ссылку на контроллер и записываю в него полные записи. В моем случае я уничтожаю их, когда я перехожу, поэтому вам придется подумать о том, как инициировать отложенную очистку. Я считаю, что он принадлежит к маршруту/контроллеру, а не к адаптеру, который является более абстрактным/глобальным. Таким образом, он содержится для конкретной функции (поиска). – aceofspades

ответ

0

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

+1

Я знаю, потому что мой параметр, который я фильтрую, не редактируется пользователем. Но как я могу кэшировать его? Предположим, что я хочу кэшировать все запросы. – Lux

1

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

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

То, что вы хотите, чтобы по существу сделать, это заменить следующий вызов:

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

с чем-то более или менее, как:

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

на самом деле, с решением ниже может выглядеть как:

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

В результате вы будете запрашивать данные один раз и всегда возвращаться из кеша в s последующие звонки.

Позвольте мне показать вам, как реализация может выглядеть следующим образом:

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

ли, что помощь в любом случае?

+0

Мы могли бы сделать api намного приятнее, чем 'cachedStore.call (это, 'findAll', ...)', например. 'This.cachedStore.findAll (...)'. Я сделал это так, потому что я действительно не знал, где именно в вашем приложении вы хотите подключиться к кэшам (только один файл - целое приложение?). Кроме того, вам может понадобиться изучить еще больше, и результаты автоматически истекают после определенного периода времени. В приведенном выше примере много вариантов, которые не были изучены, просто хотели показать направление. Если что-то нуждается в дополнительном объяснении, пожалуйста, дайте мне знать –

Смежные вопросы