AngularJS范围整数未在模板上更新

时间:2015-06-05 19:42:16

标签: javascript angularjs

我有这个非常简单的模板:

{{ polygonDotsCount }}

这个代码在控制器上:

$scope.polygonDotsCount = 0;
$scope.polygonClick = function() {
    $scope.polygonDotsCount = $scope.polygonDotsCount + 1;
    console.log($scope.polygonDotsCount);
};

每次点击地图时都会调用polygonClick,我看到控制台中的数字增加了,但模板上的数字没有增加!这有什么可能是错的?

3 个答案:

答案 0 :(得分:1)

当您在点击谷歌地图事件时更新范围变量polygonDotsCount时,代码将运行,但更改的范围变量永远不会在html上更新。因为摘要周期不会运行。为了更新所有绑定摘要周期必须具备。如果您在角度上下文中进行任何操作,将适当地应用摘要周期&将更新html上的绑定。但是,当你运行任何事件,如onclick或外部事件,如你使用谷歌地图事件,永远不会运行摘要周期。在这种情况下,您需要手动运行它。

When to run $apply

要手动运行摘要周期,您需要调用将运行$apply()方法的scope $digest()方法并更新所有绑定。但是直接调用$apply()来运行digest周期会导致问题,因为有时候当你运行摘要周期时会发生这种情况。如果当前已经存在摘要周期,那么它将抛出$digest is already in progress

的错误

你应该使用$timeout

$ 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;