Лучшая практика Angularjs для хранилища данных
В моем приложении angular есть 2 контроллера. Моя проблема в том, что контроллеры не хранят данные, когда пользователь переходит от страницы.
Как сохранить выбранные данные на моих контроллерах в хранилище данных, чтобы их можно было использовать между другими контроллерами?
Ответы
Ответ 1
Вариант 1 - пользовательский service
Вы можете использовать специальную службу angular для хранения и обмена данными между контроллерами (услуги - это объекты одного экземпляра)
определение службы
app.service('commonService', function ($http) {
var info;
return {
getInfo: getInfo,
setInfo: setInfo
};
// .................
function getInfo() {
return info;
}
function setInfo(value) {
info = value;
}
});
использование в нескольких контроллерах
app.controller("HomeController", function ($scope, commonService) {
$scope.setInfo = function(value){
commonService.setInfo(value);
};
});
app.controller("MyController", function ($scope, commonService) {
$scope.info = commonService.getInfo();
});
Вариант 2 - html5 localStorage
Вы можете использовать встроенное локальное хранилище браузера и хранить свои данные из любого места
писать
$window.localStorage['my-data'] = 'hello world';
чтение
var data = $window.localStorage['my-data']
// ...
Вариант 3 - через веб-сервер api
Если вам нужно сохранить данные среди разных пользователей, вы должны сохранить их где-нибудь на стороне сервера (db/cache)
function getProfile() {
return $http.get(commonService.baseApi + '/api/profile/');
}
function updateProfile(data) {
var json = angular.toJson(data);
return $http.post(commonService.baseApi + '/api/profile/', json);
}
Ответ 2
РЕДАКТИРОВАТЬ См. ответ Jossef Harush, где он написал подробный ответ, который охватывает другие методы, включая этот.
Я бы рекомендовал использовать либо localStorage, либо sessionStorage - http://www.w3schools.com/html/html5_webstorage.asp.
Локальное хранилище HTML предоставляет два объекта для хранения данных на клиенте:
- window.localStorage - хранит данные без истечения срока действия
- window.sessionStorage - сохраняет данные за один сеанс (данные теряются, когда вкладка браузера закрыта)
Это предполагает, что вы не хотите, чтобы POST/PUT данные передавались на ваш веб-сервис (упоминание службы Windows в вашем вопросе).
Если данные - это массив или какой-то вид, вы можете преобразовать его в JSON для хранения в виде строки, а затем, когда вам это нужно, вы можете проанализировать его следующим образом: Как сделать Я храню массив в localStorage?:
var names = [];
names[0] = prompt("New member name?");
localStorage["names"] = JSON.stringify(names);
//...
var storedNames = JSON.parse(localStorage["names"]);
Ответ 3
Есть вариант, не упомянутый в других ответах (AFAIK).
СОБЫТИЯ
-
Вы можете использовать события для связи между контроллерами.
-
Это прямое общение, которое не нуждается в посреднике (например, в услуге) и не может быть стерто пользователем (например, в хранилище HTML).
-
Весь код написан на контроллерах, с которыми вы пытаетесь установить связь, и поэтому очень прозрачен.
Хороший пример того, как использовать события для связи между контроллерами, можно увидеть ниже.
Издатель - это область, которую я хочу опубликовать (другими словами, пусть другие узнают, что что-то произошло). Большинству наплевать на то, что произошло, и они не являются частью этой истории.
Подписчик - это тот, кто заботится о том, чтобы определенное событие было опубликовано (другими словами, когда он получает уведомление, эй, это произошло, он реагирует).
Мы будем использовать $ rootScope в качестве посредника между издателем и подписчиком. Это всегда работает, потому что независимо от того, какая область генерирует событие, $ rootScope является родителем этой области или родителем родительского элемента родителя. Когда $ rootScope передает (сообщает всем, кто наследует) о событии, все слышат (так как $ rootScope просто что, корень дерева наследования области), поэтому любая другая область в приложении является дочерней по отношению к ней или дочерней по отношению к дочернему элементу.
// publisher
angular.module('test', []).controller('CtrlPublish', ['$rootScope','$scope',
function ($rootScope, $scope) {
$scope.send = function() {
$rootScope.$broadcast('eventName', 'message');
};
}]);
// subscriber
angular.module('test').controller('ctrlSubscribe', ['$scope',
function ($scope) {
$scope.$on('eventName', function (event, arg) {
$scope.receiver = 'got your ' + arg;
});
}]);
Выше мы видим, что два контроллера передают сообщение друг другу, используя событие. У события есть имя, оно должно быть уникальным, в противном случае подписчик не различает события. Параметр события содержит автоматически сгенерированные, но иногда полезные данные, сообщение является полезной нагрузкой. В этом примере это строка, но это может быть любой объект. Поэтому просто поместите все данные, которые вы хотите передать, внутри объекта и отправьте их через событие.
НОТА:
Вы можете избежать использования корневой области действия для этой цели (и ограничить число контроллеров, которые получают уведомления о событии) в случае, если две области находятся в прямой линии наследования друг от друга. Дальнейшее объяснение ниже:
$ rootScope. $ emit позволяет только другим слушателям $ rootScope его перехватить. Это хорошо, когда вы не хотите, чтобы все $ scope получали его. В основном общение высокого уровня. Думайте об этом как о взрослых, разговаривающих друг с другом в комнате, чтобы дети не могли их слышать.
$ rootScope. $ broadcast - это метод, который позволяет почти всем слышать его. Это было бы равносильно тому, что родители кричат, что ужин готов, поэтому все в доме его слышат.
$ scope. $ emit - это когда вы хотите, чтобы $ scope и все его родители и $ rootScope услышали событие. Это ребенок, который ныет родителям дома (но не в продуктовом магазине, где другие дети могут слышать). Это ярлык для использования, когда вы хотите общаться с издателем, который является дочерним или n-ным дочерним элементом подписчика.
$ scope. $ broadcast - для самого $ scope и его потомков. Это ребенок шепчет своим чучелам, чтобы их родители не могли слышать.
РЕДАКТИРОВАТЬ: Я думал, что plunker с более сложным примером будет достаточно, поэтому я решил оставить здесь все просто. Это подробное объяснение должно быть лучше.
Ответ 4
Для обмена данными между двумя контроллерами на одной странице вы можете использовать фабрики/службы. Взгляните на например, совместное использование данных между контроллерами AngularJS.
Однако, если это перегружает/обновляет страницы, вам нужно будет хранить данные в локальном хранилище, а затем читать их при перезагрузке. Пример этого: Как хранить данные в локальном хранилище с помощью Angularjs?
Ответ 5
Оформить заказ этой библиотеки https://www.npmjs.com/package/angularjs-store
Это может помочь вам намного проще управлять состоянием вашего приложения, так как оно заставит вас использовать односторонний поток данных для вашего приложения.