2017-08-01 22 views
0

我遇到一個奇怪的問題,那就是用新數據替換了$ rootScope.data.vehicles中的值,但我的舊數據點視圖與新數據一起保持約一秒鐘。

例如,在我用新數組替換$ rootScope.data.vehicles數組後,我的視圖會先顯示3個新值,然後是3箇舊值。 View正在使用ng-repeat在$ rootScope.data.vehicles上顯示切片。

immediately after replacing array

約一秒鐘後,3箇舊值在視圖中不再顯示。

one second after replacing array

每次時間間隔觸發我得到其次是舊值新值,即使值都沒有改變。

interval continues to refresh

我的控制器和工廠看起來像這樣:

(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); 
}()); 

首先我加載陣列然後我啓動$間隔定時器,刷新值每隔10秒。只要dataService返回新的值列表並將它們放入$ rootScope.data.vehicles中,我會注意到六個貼圖,而不是3個。之後,我只剩下3個新的貼圖。

我的觀點看起來像這樣:

<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> 

任何想法,如何讓我的瓷磚無縫刷新?所有的幫助非常感謝。

+1

只是一種預感,而是嘗試通過$指數將跟蹤你的NG-重複。另外,如果你實際上用每次迭代來更新數組,而不是覆蓋所有的值,我認爲你的界面看起來會更少跳躍和更清晰。 –

+2

那麼你爲什麼使用'$ rootScope'?我認爲使用'$ scope'只會讓你的代碼更具可讀性和可管理性。另外,什麼是'dataService',它有什麼作用? –

+0

Mike Feltman你是贏家!這絕對解決了我的問題。太感謝了。我認爲你應該將此作爲這個問題的答案發布,並且將其標記爲這樣。 – Ian

回答

2

當存在唯一的屬性標識符以處理時,請避免track by $index

<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> 

從文檔:

如果您使用的是具有唯一標識符屬性對象時,你應該通過這個標識符,而不是對象實例跟蹤。如果稍後重新加載數據,ngRepeat將不必爲其已經呈現的項目重建DOM元素,即使集合中的JavaScript對象已被替換爲新元素。對於大型集合,這顯着提高了渲染性能。

— AngularJS ng-repeat Directive API Reference - Tracking

+0

謝謝你的擡頭。更新了我所有'track by'語句以在對象上使用唯一ID。目前效果很好。 – Ian

1

Mike Feltman在上述評論中解決了這個問題。這非常簡單,只需在視圖中爲ng-repeat標記添加'track by $ index'即可。看到這裏:

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

<article class="icon-gallery flexslider"> 
    <section> 
     <figure ng-repeat="vehicle in $parent.data.vehicles track by $index" 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> 

希望這篇文章將有助於在未來遇到同樣類型的問題的人。

0

IIRC,內部Angular發現車輛陣列發生了變化並立即呈現,然後清理乾淨。通過$ index添加軌道到ng-repeat基本上應該強制渲染從每一次的第一項開始。

我確實同意另一篇關於使用$ rootScope的文章。如果您試圖使車輛在全球範圍內可用,而不是將其存儲在rootScope中,請將它們存儲在數據服務中,並在需要時進行注入。這將是一個更清潔的方法。

+0

感謝您的提示。我已經從$ rootScope中刪除了它們。 – Ian

相關問題