AngularJS сообщает о событии / переходе от сервиса к контроллеру

0

Я пытаюсь установить связь между двумя контроллерами. Я знаю, что это можно сделать, подняв событие, а затем используя $ rootScope. $ Broadcast, но не рекомендуется для крупномасштабных приложений. Я видел много сообщений в блогах, которые рекомендуют использовать службу для общения, но не могут преуспеть в реализации. Мой фактический код более сложный, но вот суть:

HTML:

<body ng-app="app">
    <div ng-controller="MainCtrl">
        <span>Source: {{count}}</span>
        <button ng-click="updateCount()">Increase Count</button>
    </div>
    <div ng-controller="ListCtrl">
        Destination: {{updatedCount}}
    </div>
</body>

JS:

(function () {

    var app = angular.module("app", []);

    app.factory("ShareDataSvc", function ($log) {

        var currentCount = 0;

        var set = function (val) {
            $log.info('Setting service value to: ' + currentCount);
            currentCount = val;
        }

        var get = function () {
            return currentCount;
        }

        return {
            set: set,
            get: get
        }
    });

    app.controller("MainCtrl", ['$scope', 'ShareDataSvc', function ($scope, ShareDataSvc) {
        $scope.count = ShareDataSvc.get();
        $scope.updateCount = function () {
            $scope.count = $scope.count + 1;
            ShareDataSvc.set($scope.count);
        }
    }]);

    app.controller("ListCtrl", ["$scope", "ShareDataSvc", function ($scope, ShareDataSvc) {
        $scope.updatedCount = ShareDataSvc.get();

        // trigger alert if count updated
        $scope.triggerAlert = function () {
            alert('Count updated!');
        }
    }]);
}());

Я пытаюсь понять, почему счетчик в пункте назначения не обновляется Angular, хотя он связан с данными. Я понимаю, что когда счетчик обновляется в SharedDataSvc, свойство updatedCount будет пересчитано. Что я здесь делаю неправильно? Конечным результатом является запуск предупреждения при каждом обновлении счетчика.

Теги:
angularjs-controller
angularjs-service

1 ответ

0
Лучший ответ

Вы столкнулись с проблемой старой копии по значению. Когда вы это сделаете

$scope.updatedCount = ShareDataSvc.get();

Обновленное свойство count устанавливается на значение, которое возвращается из вашей функции get, и поэтому не видит будущих изменений в отслеживаемом в вашей службе значении. У вас есть два варианта обойти это. Один из них - добавить часы к каждому из ваших контроллеров для отслеживания значения в службе. Не идеально. Во-вторых, чтобы свойство объекта в вашей службе отслеживало значение, а данные связывают этот объект с вашей областью. Что-то вроде (заметьте, я показываю только интересные части):

app.factory("ShareDataSvc", function ($log) {

    var set = function (val) {
        $log.info('Setting service value to: ' + currentCount);
        this.data.count = val;
    }

    return {
        data: {count: 0}
        set: set
    }
});

app.controller("MainCtrl", ['$scope', 'ShareDataSvc', function ($scope, ShareDataSvc) {
    $scope.data = ShareDataSvc.data;
    $scope.updateCount = function () {
        ShareDataSve.data.count++; // and increment function in the service would be better
    }
}]);

app.controller("ListCtrl", ["$scope", "ShareDataSvc", function ($scope, ShareDataSvc) {
    $scope.data = ShareDataSvc.data;

}]);

Затем в вашем HTML

<body ng-app="app">
    <div ng-controller="MainCtrl">
        <span>Source: {{data.count}}</span>
        <button ng-click="updateCount()">Increase Count</button>
    </div>
    <div ng-controller="ListCtrl">
        Destination: {{data.count}}
    </div>
</body>
  • 0
    Ах .. Я вижу проблему. Привязка к фактическому значению обновляет счет в месте назначения. Но я все еще не знаю, как вызвать предупреждение. Является ли $ watch единственным вариантом?
  • 0
    Это зависит от вашего варианта использования. Если вам нужно знать, когда он изменяется в ваших контроллерах, вам нужно будет либо наблюдать, либо отправлять событие на rootScope из службы, которую можно прослушивать в вашем контроллере (более производительной, чем часы).
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню