我试图用2个控制器和2个服务创建一个简单的例子,其中一个服务每3秒调用一次。
controller1调用服务,该服务更改controller2中使用的值。我将值传递给另一个服务,但是只有在我按下“停止”后,我的html页面上的值才会更新。我的例子的按钮(在下面)。
我可以在每次投票时更新页面值吗?
<html ng-app="myApp">
<head>
<title>MyApp</title>
<script src="angular.js"></script>
<script>
var app = angular.module('myApp',[]);
app.service('SimpleService', function() {
var _value = 0;
var setValue = function(v) {
_value = v;
}
var getValue = function(){
return _value;
}
return {
setValue: setValue,
getValue: getValue
};
})
app.service('PollService', function(SimpleService) {
var poll = undefined;
var startPolling = function(){
poll = setInterval(function(){
console.info('poll...');
console.info(SimpleService.getValue());
SimpleService.setValue(SimpleService.getValue()+1);
}, 3000);
}
var stopPolling = function(){
clearInterval(poll);
}
return {
startPolling: startPolling,
stopPolling: stopPolling
};
})
app.controller('Controller1',function($scope, PollService){
var poll = undefined;
$scope.startPolling = function(){
PollService.startPolling();
}
$scope.stopPolling = function(){
console.info('stop');
PollService.stopPolling();
}
});
app.controller('Controller2', function($scope, SimpleService){
$scope.newVal = function(){
return SimpleService.getValue();
}
});
</script>
</head>
<body>
<div ng-controller="Controller1">
<button ng-click="startPolling()">Start</button>
<button ng-click="stopPolling()">Stop</button>
<br/>
<br/>
</div>
<div ng-controller="Controller2">
<h5>New value: {{newVal()}}</h5>
</div>
</body>
问候。
答案 0 :(得分:3)
每次在SimpleService中调用setter时,都需要调用摘要周期。除非新的摘要周期开始,否则视图绑定不会更新。这是工作代码段。
app.service('SimpleService', function($rootScope) {
var _value = 0;
var setValue = function(v) {
_value = v;
$rootScope.$apply(); //added this here
}
var getValue = function(){
return _value;
}
return {
setValue: setValue,
getValue: getValue
};
})
你需要做scope.apply()。 $ apply评估模板中的任何表达式并开始一个新的摘要周期。在$ digest阶段,作用域检查所有$ watch表达式并将它们与之前的值进行比较。您可以查看有关它的文档here。
我在您的代码中注意到的其他一些问题:
app.controller('Controller2', function($scope, SimpleService2){
$scope.newVal = function(){
return SimpleService.getValue();
}
});
在此处,将名称更正为SimpleService。
没有stopPropagation方法。我在PollService中按如下方式添加它以使代码正常工作:
var stopPolling = function(){
clearInterval(poll);
}
答案 1 :(得分:1)
由于setInterval不是一个角度函数,因此angular不知道该值是否已更新,并且无法告诉DOM该值是脏的,因此不会更新。
如果您想继续使用true
而不是angular的$ interval,可以将setInterval
注入您的投票服务,然后您可以使用$rootScope
来消化将更新的值DOM。你可以做到
$rootScope.$apply
在$rootScope.$apply(function(){
SimpleService.setValue(SimpleService.getValue()+1);
});
功能中。
否则,setInterval
是$interval
函数的angular.js包装器,不需要手动调用$ apply。
我对您的代码和一些示例进行了更改,以便您可以更好地构建在控制器范围内使用服务的方式。
主要是,由于服务是一个对象,我们可以通过将服务本身添加到控制器作用域来直接引用DOM中的服务上下文,而不是引用单个对象键。这消除了从DOM调用getter函数的需要(就像调用{{newValue()}}时那样。)