AngularJS:深度对象修改后视图不更新

AngularJS: view not updating after deep object modification

本文关键字:后视图 更新 修改 对象 深度 AngularJS      更新时间:2023-09-26

我有这个html代码:

<table class="table table-striped table-condensed table-hover">
    <tbody>
        <tr ng-repeat="doc in container.Documents ">
                {{doc.Status.Message}}
            </td>
            <!-- .... -->
        </tr>
    </tbody>
</table

而这个 Angularjs 控制器:

(function (ng, app) {
    "use strict";
    app.controller(
        "my.DocumentsController",
        function ( $scope, $stateParams, MYContainer, $timeout ) {
            $scope.container = new MYContainer();            
            $scope.$watch('container', function (newVal, oldVal) {
                $timeout(function () {
                    $scope.$apply();
                }, 0);
            }, true);
            $scope.container.load($stateParams.Id);
    });
})(angular, my_app);

MYContainer的负载函数:

function load(id) {
    var scope = this;
    var deffered = $q.defer();
    containerService.getData(id, "true").success(function (data) {
        angular.extend(this, data);
        deffered.resolve();
    }).error(function (e) {
        deffered.reject('Error while loading container');
    });
    return deffered.promise;
}

问题是每当我重新加载批处理(使用修改后的容器。文档),它不会在 html 视图中显示修改后的批处理。

我已经阅读了有关角度中的平等手表的信息,所以我在控制器中添加了监视函数,它确实检测到监视函数中的修改,所以我调用 $scope.$apply(),但它在 html 中没有变化。

如果我在 $timeout 调用中输入 200 毫秒而不是 0,则视图会发生变化。

您不需要

在这里使用任何观察者或$apply,angular 能够处理这个问题并在数据更改时更新视图。此外,$watchers在性能方面是昂贵的,除非绝对必要,否则建议避免使用 $scope.$apply,但此处没有。

$angular.extend不是深副本。你可以在这里阅读它。

我建议你将代码更改为:

load($stateParams.Id).then(function(result) {
    $scope.container = result;
});

并从success回调中删除angular.extend(this, data);

还要删除整个$watch部分,这是多余的。

在$watch中调用 $timeout(0) 或 $apply 是没有意义的,因为$watch本身是由摘要调用的 - 调用$apply的目的是触发摘要。

相反,您希望在异步更改数据时强制使用此摘要 - 在本例中,在解析加载承诺时。