Хранение данных, моделируемых KnockoutJS, с помощью AmplifyJS
Я пытаюсь найти способ кэширования моих нокаутированных данных SPA SPA, и я экспериментировал с ampifyJS. Вот одна из моих функций GET:
UserController.prototype.getUsers = function() {
var self = this;
return $.ajax({
type: 'GET',
url: self.Config.api + 'users'
}).done(function(data) {
self.usersArr(ko.utils.arrayMap(data.users, function(item) {
// run each item through model
return new self.Model.User(item);
}));
}).fail(function(data) {
// failed
});
};
Вот та же функция, "усиленная":
UserController.prototype.getUsers = function() {
var self = this;
if (amplify.store('users')) {
self.usersArr(ko.utils.arrayMap(amplify.store('users'), function(item) {
// run each item through model
return new self.Model.User(item);
}));
} else {
return $.ajax({
type: 'GET',
url: self.Config.api + 'users'
}).done(function(data) {
self.usersArr(ko.utils.arrayMap(data.users, function(item) {
// run each item through model
return new self.Model.User(item);
}));
}).fail(function(data) {
// failed
});
};
Это работает, как и ожидалось, но я не уверен в подходе, который я использовал, потому что это также потребует дополнительной работы над addUser
, removeUser
а также editUser
функции. И так как у меня в приложении много других похожих функций, я бы хотел избежать лишнего кода, если это возможно.
Я нашел способ справиться с вещами с помощью ko.extenders
, вот так:
this.usersArr = ko.observableArray().extend({ localStore: 'users' });
Затем используйте ko.extenders.localStore
функция для обновления данных локального хранилища всякий раз, когда он обнаруживает изменение внутри observableArray
, Так что при инициализации он напишет observableArray
в случае, если локальное хранилище данных существует для users
ключ и при изменениях он обновит данные локального хранилища.
Моя проблема с этим подходом заключается в том, что мне нужно провести мои данные через модель, и я не смог найти способ сделать это из localStore
функция, которая хранится на отдельной странице.
Кто-нибудь из вас работал с KO и Amplify? Какой подход вы использовали? Должен ли я использовать первый или попробовать комбинацию двух и переписать расширитель таким образом, чтобы он только обновлял локальное хранилище, не записывая в observableArray
на init?
1 ответ
После обсуждения в комментариях к вопросу я предложил использовать собственное кэширование HTTP вместо добавления другого уровня кэширования на клиенте с помощью дополнительной библиотеки.
Это потребовало бы реализации схемы условного запроса.
Такая схема опирается на информацию о свежести в заголовках ответа Ajax через Last-Modified
(или же E-Tag
) HTTP-заголовки и другие заголовки, которые влияют на кэширование браузера (например, Cache-Control:
с его различными вариантами).
Браузер прозрачно отправляет
If-Modified-Since
(или жеIf-None-Match
) заголовок на сервер, когда тот же ресурс (URL) запрашивается впоследствии.Сервер может ответить HTTP
304 Not Modified
если информация о клиенте все еще актуальна. Это может быть намного быстрее, чем воссоздание полного ответа с нуля.С точки зрения Ajax-запроса (jQuery или иным образом) ответ работает одинаково, независимо от того, был ли он на самом деле с сервера или из кеша браузера, последний работает намного быстрее.
Для этого необходима тщательная адаптация серверной части, а клиентская сторона не требует особых изменений.
Преимущество реализации условных запросов - снижение нагрузки на сервер и более быстрое поведение ответа на клиенте.
Специальность Knockout, чтобы улучшить это еще дальше:
Если вам случится использовать плагин сопоставления для сопоставления необработанных данных сервера со сложной моделью представления, вы можете определить - как часть параметров, управляющих процессом сопоставления - key
функция. Его цель - сопоставить части вашей модели представления с частями исходных данных.
Таким образом, части данных, которые уже были сопоставлены, не будут отображаться снова, остальные обновляются. Это может помочь сократить время обработки клиентом данных, которые у него уже есть, и, возможно, ненужные обновления экрана.