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



我想在我的应用程序中执行某些逻辑时显示按钮(某些按钮),然后隐藏此按钮。

通过单击某个按钮,我调用expand(),其中将数据.加载设置为true,此时我想要按钮出现,当我将data.load设置为false时,我想按钮隐藏,但视图不是更新。

<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 - 不更新视图。

通过$scope属性引用数据模型,并将主逻辑移出当前摘要周期(使用 $timeout$evalAsync ),应该可以解决"$apply正在进行中"消息:

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

我通常更喜欢 (1) 在服务中保存加载进度,以及 (2) 使用承诺来管理进度状态。在下面的示例中,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中的更多文档)。

$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
}
按照

@Sreehari的建议使用$scope.data.loading,并在视图中使用ng-if而不是ng-show

最新更新