如何在Angular中更新视图(避免$ apply已在进行中)?

时间:2017-01-30 13:56:13

标签: javascript angularjs

我希望在我的应用程序中显示按钮(某些按钮),然后隐藏此按钮。

通过单击Some Button我调用expand(),其中set data.loading为true,此时我想按钮出现,当我将data.loading设置为false时我想按钮隐藏,但是视图不是更新。< / p>

<button ng-show="data.loading">Some Button</button>
<button ng-click="expand(data)">Other Button</button>

功能:

$scope.expand = function (data) {
    data.loading = true;
    // Some Button must be visible now
    // Some logic here;
    data.loading = false;
    // Some Button must be invisible now
}

$ scope。$ apply() - 返回错误:$ apply已在进行中

$ scope.safeApply() - 不会抛出异常,但不会更新视图。

$ timeout - 不更新视图。

3 个答案:

答案 0 :(得分:2)

通过$scope属性引用您的数据模型以及将主逻辑移出当前摘要周期(使用$timeout or $evalAsync)应修复您的“$ apply in progress”消息:

$scope.expand = function () {
   $scope.data.loading = true;
   $timeout(function () {
       // Some logic here;
       $scope.data.loading = false;
   });
};

我通常更喜欢(1)在服务中保持加载进度,以及(2)使用promises来管理进度状态。在下面的示例中,logicFunction()返回一个承诺。

$scope.expand = function () {
    progressStatusService.started("Loading something…")
    logicFunction().finally(function () {
        progressStatusService.finished("Loading something…")
    });
};
// progressStatusService implementation left as a challenge to the reader

全局进度服务主要用于应用程序范围的加载指示 - 如果加载状态仅影响一个特定的窗口小部件,那么它可能是一个开销。

但是,延迟/承诺方法通常很有用且更易于阅读(请参阅$q上的更多文档)。

答案 1 :(得分:1)

$scope.expand = function () {
   $scope.data.loading = true;
   // Some Button must be visible now
   // Some logic here;
   $scope.data.loading = false;
   // Some Button must be invisible now
}

答案 2 :(得分:0)

按照@Sreehari的建议使用$scope.data.loading并在您查看中使用ng-if而不是ng-show