我简化了我的实际代码,但问题是一样的。在“第一个控制器”中单击Start counter
匿名函数后,开始更改myService
中的数据。首先它工作正常。但切换到“第二个控制器”后,即使您导航回“第一个控制器”,Angular也会停止自动更新<span ng-bind="getData().data">
的值。
但是,如果您来回切换控制器,您可以看到控制器负载上的跨度正在更新,因此数据正在发生变化,控制器可以访问它。只是Angular不再自动跟踪它了。
如何让Angular在再次切换控制器后开始跟踪更改并更新元素?
<html>
<head>
<script src="https://code.angularjs.org/1.4.0-beta.4/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.0-beta.4/angular-route.min.js"></script>
</head>
<body>
<div style="padding: 0 0 20px 0">
<a href="#/first">First controller</a> | <a href="#/second">Second controller</a>
</div>
<div ng-app="myApp">
<div ng-view></div>
<script type="text/ng-template" id="temp1.html">
Data: <span ng-bind="getData().data"></span>
<br/>
<button ng-click="start()">Start counter</button>
</script>
<script type="text/ng-template" id="temp2.html">
Data: <span ng-bind="getData().data"></span>
</script>
</div>
<script type="text/javascript">
var myControllers = angular.module('myControllers', []);
myControllers.factory('myService', [function() {
return { data: 0 };
}]);
myControllers.controller('myController1', ['$scope', 'myService', function($scope, myService){
$scope.getData = function() {
return myService;
}
$scope.start = function() {
setInterval(function() {
myService.data++;
$scope.$apply();
}, 1000)
}
}]);
myControllers.controller('myController2', ['$scope', 'myService', function($scope, myService){
$scope.getData = function() {
return myService;
}
}]);
var myApp = angular.module('myApp', [
'ngRoute',
'myControllers'
]);
myApp.config(['$routeProvider',function($routeProvider) {
$routeProvider.
when("/first",{ controller: "myController1", templateUrl: "temp1.html"}).
when("/second", {controller: "myController2", templateUrl: "temp2.html"}).
otherwise({redirectTo : "/first"});
}]);
</script>
</body>
</html>
答案 0 :(得分:0)
所以我实际上在这里找到了答案:Passing data between controllers using service and confusion with using [ '$scope' , 'service' , function($scope, service){}](见 Anthony Chu于2014年2月17日6:12 的评论)。诀窍是使用$rootController
通过事件警告所有其他控制器以更新服务中的数据。因此,匿名函数将在后台运行,而不会引用新的$scope
,但新$scope
将通过$rootScope
事件向下传播从其接收消息。
我已将$root.$broadcast(...)
附加到匿名函数,并将相应的$scope.$on(...)
附加到两个控制器。所以控制器代码现在看起来像这样:
myControllers.controller('myController1', ['$scope', 'myService', '$interval', '$rootScope',
function($scope, myService, $interval, $rootScope) {
$scope.getData = function() {
return myService;
}
$scope.$on('myupdate', function() {
if (!$scope.$$phase) { //checks that Angular is not updating scope right now
$scope.$apply();
}
});
$scope.start = function() {
setInterval(function() {
myService.data++;
$rootScope.$broadcast('myupdate');
}, 1000)
}
}]);
myControllers.controller('myController2', ['$scope', 'myService',
function($scope, myService) {
$scope.getData = function() {
return myService;
}
$scope.$on('myupdate', function() {
if (!$scope.$$phase) {
$scope.$apply();
}
});
}]);