Angular ng-repeat causes flickering

こ雲淡風輕ζ 提交于 2019-12-03 08:36:03

问题


I'm displaying a list of thumbnails with this code:

<div class ="channel" ng-repeat ="channel in UIModel.channels" ng-class ="{evenchannel: ($index % 2) == 0, oddchannel: ($index % 2) == 1}">
            <img class="channel-img" ng-src ="data/channels/{{$index + 1}}/thumb"/>
</div>

In the controller I have an ajax request which grabs new thumbnail images. Angular thus updates the images but causes flickering. Is there a way to double buffer or not have the list deleted in the process of updating the DOM?


回答1:


To go along with @cexbrayat's answer, if you don't have any IDs you can also just associated it and track by $index. Which is an internal iteration # during an ng-repeat.

<div ng-repeat="channel in UIModel.channels track by $index"></div>



回答2:


You can use track by in your ng-repeat with a unique identifier. If I suppose your channel object has an id, you can do :

<div class ="channel" ng-repeat="channel in UIModel.channels track by channel.id"></div>

The tracking avoids the complete DOM deletion and recreation at every updates, as Angular will be able to track if the element is the same as previously and will keep the DOM element.




回答3:


Try the answers from @Mark Pieszak and @cexbrayat first, however if you are using ngAnimate in your application, they may not completely solve your problem.

In addition to:

<div class="channel" ng-repeat="channel in UIModel.channels track by channel.id"></div>

I needed to add the following CSS to disable animation for this ng-repeat:

.channel .ng-leave, .channel .ng-leave-active {
    display: none !important;
}

.channel .ng-move, .channel .ng-move-active {
    display: none !important;
}

This ensures that once the animation starts, the item is immediately hidden. The alternatives are to actually use an animation, or to disable the animation on the element in code with $animate.enabled('div.channel', false);.




回答4:


I was having the same issue, using the track by $index finally resolved the problem for me. At first I didn't think it did, as I used it directly in the image tags where another ng-repeat was. Once I put it in the parent div (as well) on ng-repeat it worked:

<div ng-repeat="item in blah track by $index">
   <!-- stuff -->
   <!-- later in this div: -->
   <img data-ng-repeat="dict in item.blah track by $index" class="smallPics ng-cloak" src="{[dict.path]}"></img>

   <!-- and the rest is blah-istory -->



回答5:


As a note:

If using track by $index doesn't update the DOM with the new values,
consider using a track by 'the properties you expect to change' just be careful to avoid ngDupe errors

e.g:

<div ng-repeat="channel in UIModel.channels track by customExp(channel)">

. . .

$scope.customExp = function(chan) {
    return chan.id+chan.thumbnail_url; // this has to ensure uniqueness
}

or

<div ng-repeat="channel in UIModel.channels track by channel.id+channel.thubnail_url">


来源:https://stackoverflow.com/questions/24144970/angular-ng-repeat-causes-flickering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!