Стратегии динамического обслуживания в AngularJS

Как я могу отключить сервис на лету и сделать так, чтобы все компоненты (зависящие от сервиса) автоматически связывались с данными новой стратегии?

у меня есть Storage сервис и две стратегии хранения, StorageStrategyA а также StorageStrategyB, Storage предоставляет открытый интерфейс для контроллеров и других компонентов для взаимодействия с:

angular.module('app').factory('Storage', function ($injector) {
    var storage;
    var setStrategy = function (name) {
        storage = $injector.get(name);
    };

    setStrategy('StorageStrategyB');

    return {
        getItems: function () {
            return storage.getItems();    
        }
        // [...]
    };
});

Но когда стратегия меняется, двусторонняя привязка разрывается, и представление не обновляется с элементами из getItems() из новой стратегии.

Я создал Plunker, чтобы проиллюстрировать проблему.

Есть ли способ объединить шаблон стратегии с AngularJS и сохранить двустороннее связывание?

Обратите внимание, что в моем настоящем приложении я не могу просто позвонить Storage.getItems() снова после того, как стратегия была изменена, потому что есть несколько компонентов (представления, контроллеры, области), на которые полагается Storage и изменение службы происходит автоматически.

Редактировать:
Я разветвлял Плункер, чтобы подчеркнуть проблему. Как видите, данные в верхней части обновляются только потому, что я вызываю вручную Storage.getItems() снова после того, как стратегия была изменена. Но я не могу этого сделать, потому что другой компонент - например, OtherController - также доступ к данным на Storage а также нужно автоматически получать свои данные из новой стратегии. Вместо этого они остаются привязанными к первоначальной стратегии.

3 ответа

Решение

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

$scope.items = Storage.getItems();

Таким образом, когда вы меняете стратегию, вы не меняете ссылку на предметы. Это все еще указывает на ссылку на элементы StrategyB.

Вы должны использовать механизм ниже, чтобы изменить ссылку.

Затем вы можете сделать что-то, где вы можете общаться между контроллерами, чтобы изменить ссылку на элементы.

Пожалуйста, найдите план, который я обновил.

$rootScope.$broadcast("updateStrategy");

А затем обновите свой список товаров и другие.

$scope.$on("updateStrategy",function(){
  $scope.name = Storage.getName();
  $scope.items = Storage.getItems(); //Here changing the reference.
  //Anything else to update
});

Двустороннее связывание все еще в порядке, у вас есть проблема со ссылкой. когда AppController устанавливает набор $scope.items для элементов StorageStrategyB, то при переключении на StorageStrategyA AppController $scope.items по-прежнему устанавливается на элементы StorageStrategyB.

angular.module('app').controller('AppController', function ($scope, Storage) {



    Storage.setStrategy('StorageStrategyB');

    $scope.current = Storage.getName();

    $scope.items = Storage.getItems();  

    $scope.setStrategy = function (name) {
        Storage.setStrategy(name);
        $scope.current = Storage.getName();
        $scope.items = Storage.getItems();  
        console.log( $scope.items);
        console.log($scope.current);
    };

    $scope.addItem = function () {
        Storage.addItem($scope.item);
        $scope.item = '';
    };

});

Ты забыл

 $scope.items = Storage.getItems(); 

хороший вопрос:)

plnkr

Другие вопросы по тегам