Лучшая практика 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

Это может помочь вам намного проще управлять состоянием вашего приложения, так как оно заставит вас использовать односторонний поток данных для вашего приложения.