2015-07-20 52 views
0

我试图在两个控制器之间进行通信。我知道这可以通过引发一个事件,然后使用$ rootScope。$ broadcast来完成,但对于大型应用程序不适用。我见过很多博客文章,建议使用服务进行沟通,但无法成功实施。我实际的代码更复杂,但这里的要点是:AngularJS沟通事件/从服务更改为控制器

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

回答

0

您遇到了旧的副本的价值问题。当你做

$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> 
+0

啊..我看到的问题。绑定到实际值会更新目标中的计数。但我仍然不确定如何触发警报。 $是唯一的选择吗? – JSRookie

+0

这取决于你的用例。如果您需要知道控制器何时发生变化,那么您需要有一个手表,或者从您的控制器中可以监听的服务在rootScope上发出一个事件(然后是手表的更高性能)。 –

+0

您是否需要示例或说明足以让您走? –

相关问题