Angular:使用ng-repeat更新$ scope的新数据会导致旧数据保留 [英] Angular: Updating $scope with new data causes old data to remain when using ng-repeat

查看:150
本文介绍了Angular:使用ng-repeat更新$ scope的新数据会导致旧数据保留的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个奇怪的问题,我用新数据替换了$ rootScope.data.vehicles中的值,但是我的视图上的旧数据点与新数据一起保留了大约一秒钟.

I'm having a strange issue where I replace the values in $rootScope.data.vehicles with new data but the old data points on my view remain for about one second alongside the new data.

例如,在用新数组替换$ rootScope.data.vehicles数组之后,我的视图将首先显示3个新值,然后显示3个旧值. View正在$ rootScope.data.vehicles上使用ng-repeat来显示图块.

For instance, right after I replace the $rootScope.data.vehicles array with a new array my view will display the 3 new values first followed by the 3 old values. View is using ng-repeat on $rootScope.data.vehicles to display tiles.

大约一秒钟后,视图中将不再显示3个旧值.

About one second later the 3 old values are no longer displayed in the view.

每次触发间隔时,即使值没有更改,我也会得到新值,然后是旧值.

Each time the interval fires I get new values followed by old values, even if the values have not changed.

我的控制器和工厂看起来像这样:

My controller and factory look like so:

(function () {
    var vehiclesInjectParams = ['$location', 'dataService', '$rootScope', 'VehiclesRefreshService'];

    var VehiclesController = function ($location, dataService, $rootScope, VehiclesRefreshService) {
        var vm = this;

        if ($rootScope.data == undefined)
            $rootScope.data = {};

        $rootScope.data.vehicles = [];

        function init() {
            dataService.getVehicles()
                .then(function (data) {
                    $rootScope.data.vehicles = data.results;
                }, function (error) {
                    var thisError = error.data.message;
                });

            VehiclesRefreshService.getValues();
        };

        init();
    };

    VehiclesController.$inject = vehiclesInjectParams;

    var vehiclesRefreshInjectParams = ['$interval', '$rootScope', '$q', 'dataService'];

    var VehiclesRefreshService = function ($interval, $rootScope, $q, dataService) {
        var factory = {};

        factory.getValues = function () {
            var interval = $interval(function () {
                dataService.getVehicles()
                .then(function (data) {
                    $rootScope.data.vehicles = data.results;
                }, function (error) {
                    var thisError = error.data.message;
                });
            }, 10000);

        };

        return factory;
    };

    VehiclesRefreshService.$inject = vehiclesRefreshInjectParams;

    angular.module('teleAiDiagnostics').controller('VehiclesController', VehiclesController).factory('VehiclesRefreshService', VehiclesRefreshService);
}());

首先,我加载数组,然后启动$ interval计时器,每隔10秒刷新一次值.一旦dataService返回新的值列表并将它们放入$ rootScope.data.vehicles,我注意到六个磁贴而不是3.一秒钟之后,我只剩下了三个新磁贴.

First I load the array then I start an $interval timer to refresh the values every 10 seconds. As soon as the dataService returns the new list of values and puts them in $rootScope.data.vehicles I notice the six tiles instead of 3. One second after that I'm left with only the 3 new tiles.

我的视图如下:

<header>
    <h1>Vehicles</h1>
</header>

<article class="icon-gallery flexslider">
    <section>
        <figure ng-repeat="vehicle in $parent.data.vehicles" class="gallery-item svg">
            <a class="nextpage" ng-href="#!/vehicle/{{vehicle.vehicleID}}">
                <img src="img/machine/01.svg" alt="">
                <span class="green-machine-code">{{vehicle.id}}</span>
            </a>
            <ul>
                <li>{{vehicle.id}}</li>
                <li>{{vehicle.ip}}</li>
                <li>Online: {{vehicle.online}}</li>
                <li>Status: {{vehicle.status}}</li>
                <li>AllClear: {{vehicle.allClear}}</li>
            </ul>
        </figure>
    </section>
</article>

关于如何使瓷砖无缝刷新的任何想法吗?感谢所有帮助.

Any ideas as to how to get my tiles to refresh seamlessly? All help is greatly appreciated.

推荐答案

当有唯一的属性标识符可使用时,请避免使用track by $index.

Avoid track by $index when there is a unique property identifier to work with.

<figure ng-repeat="vehicle in $parent.data.vehicles track by ̲v̲e̲h̲i̲c̲l̲e̲.̲i̲d̲ ̶$̶i̶n̶d̶e̶x̶" class="gallery-item svg">
    <a class="nextpage" ng-href="#!/vehicle/{{vehicle.vehicleID}}">
        <img src="img/machine/01.svg" alt="">
        <span class="green-machine-code">{{vehicle.id}}</span>
    </a>
    <ul>
        <li>{{vehicle.id}}</li>
        <li>{{vehicle.ip}}</li>
        <li>Online: {{vehicle.online}}</li>
        <li>Status: {{vehicle.status}}</li>
        <li>AllClear: {{vehicle.allClear}}</li>
    </ul>
</figure>

从文档中:

如果要使用具有唯一标识符属性的对象,则应按此标识符而不是对象实例进行跟踪.如果以后要重新加载数据,即使集合中的JavaScript对象已替换为新对象,ngRepeat也不必为其已呈现的项目重建DOM元素.对于大型馆藏,这可以显着提高渲染性能.

If you are working with objects that have a unique identifier property, you should track by this identifier instead of the object instance. Should you reload your data later, ngRepeat will not have to rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones. For large collections, this significantly improves rendering performance.

> AngularJS ng-repeat指令API参考-跟踪

这篇关于Angular:使用ng-repeat更新$ scope的新数据会导致旧数据保留的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆