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

时间:2015-01-21 13:22:30

标签: javascript angularjs

我有这个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;
}

问题在于每当我重新加载批处理(使用修改后的container.Documents)时,它都不会在html视图中显示修改后的批处理。

我已经阅读了有关角度的等式监视器,所以我在控制器中添加了监视功能,它确实检测到监视功能中的修改,因此我调用$ scope。$ apply()但它在html中没有改变。

如果我在$ timeout调用中放入200毫秒而不是0,则视图会被更改。

2 个答案:

答案 0 :(得分:3)

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

$angular.extend不是深层副本。你可以阅读它here

我建议您将代码更改为:

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

angular.extend(this, data);回调中移除success

同时删除整个$watch部分,这是多余的。

答案 1 :(得分:1)

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

相反,您希望在异步更改数据时强制使用此摘要 - 在这种情况下,解决加载承诺时。