代码之家  ›  专栏  ›  技术社区  ›  JSRookie

AngularJS将事件/更改从服务传递到控制器

  •  0
  • JSRookie  · 技术社区  · 10 年前

    我试图在两个控制器之间进行通信。我知道这可以通过引发事件然后使用$rootScope来完成$广播,但不适合大规模应用。我看过很多博客文章,建议使用服务进行通信,但都未能成功实现。我的实际代码更复杂,但要点如下:

    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属性将被重新计算。 我在这里做错了什么?最终结果是在每次计数更新时触发警报。

    1 回复  |  直到 10 年前
        1
  •  0
  •   Gordon Bockus    10 年前

    你遇到了旧的价值问题。当你这样做的时候

    $scope.updatedCount = ShareDataSvc.get();
    

    更新的计数属性被设置为从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>