我有这个非常简单的模板:
{{ polygonDotsCount }}
这个代码在控制器上:
$scope.polygonDotsCount = 0;
$scope.polygonClick = function() {
$scope.polygonDotsCount = $scope.polygonDotsCount + 1;
console.log($scope.polygonDotsCount);
};
每次点击地图时都会调用polygonClick,我看到控制台中的数字增加了,但模板上的数字没有增加!这有什么可能是错的?
答案 0 :(得分:1)
当您在点击谷歌地图事件时更新范围变量polygonDotsCount
时,代码将运行,但更改的范围变量永远不会在html上更新。因为摘要周期不会运行。为了更新所有绑定摘要周期必须具备。如果您在角度上下文中进行任何操作,将适当地应用摘要周期&将更新html上的绑定。但是,当你运行任何事件,如onclick
或外部事件,如你使用谷歌地图事件,永远不会运行摘要周期。在这种情况下,您需要手动运行它。
要手动运行摘要周期,您需要调用将运行$apply()
方法的scope
$digest()
方法并更新所有绑定。但是直接调用$apply()
来运行digest
周期会导致问题,因为有时候当你运行摘要周期时会发生这种情况。如果当前已经存在摘要周期,那么它将抛出$digest is already in progress
你应该使用$timeout
,
它实际上运行digest
个周期,但它有一个优点。当您在$timeout
函数中编写代码时,它将被执行并且&将运行摘要周期。但是在运行该摘要周期时,先前正在运行的digest
正在进行中,然后它等待该摘要周期结束&然后在完成该摘要后执行它将运行自己的摘要周期。
<强>代码强>
$scope.polygonDotsCount = 0;
$scope.polygonClick = function() {
$timeout(function(){ //<-- inject $timeout on controller before using it.
$scope.polygonDotsCount = $scope.polygonDotsCount + 1;
console.log($scope.polygonDotsCount);
});
};
使用$ timeout将确保它永远不会与其他冲突 运行摘要周期
答案 1 :(得分:0)
好吧,使用不同的非角度库似乎是一个问题。我正在使用Google地图和-di-lab.com/polygon
的修改版本出于某种原因,即使我在控制台上看到范围正在更新,HTML也不会更新,所以我用这个函数强制更新:
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
如果有人能解释为什么会发生这种情况以及解决问题的更好方法,我会选择他们的答案。
答案 2 :(得分:0)
此问题与摘要周期有关。
如果AngularJS通常将我们的代码包装在$ apply()中并启动$ digest循环,那么你何时需要手动调用$ apply()?实际上,AngularJS非常清楚。它只会考虑在AngularJS上下文中完成的那些模型更改(即更改模型的代码包含在$ apply()中)。 Angular的内置指令已经这样做,因此您所做的任何模型更改都会反映在视图中。但是,如果更改Angular上下文之外的任何模型,则需要通过手动调用$ apply()来通知Angular更改。这就像告诉Angular您正在更改某些模型,它应该激活观察者,以便您的更改正确传播。
有关详细信息,请参阅&#34; jsFiddle&#34;