Shyamal Parikh
Shyamal Parikh

Reputation: 3068

Flicker on data update Angularjs

I have a collection of users which needs to be updated incase the data is changed in the database. For this I am calling the update function from the controller.

In Controller

$scope.update = function(){
    $http.get("....")
    .success(function(data){
        $scope.users = data;
    })
};

In Template

<div ng-repeat="user in users">
  ...
</div>

Div flicker can be noticed on update function call. Is there a way to avoid this?

Upvotes: 2

Views: 3464

Answers (2)

MarcinC
MarcinC

Reputation: 71

I had the same problem. Was looking for some solution other than mine. Probably this is the only one.

Root cause of the 'flickering' is recreating DOM because you assign new, plain object to the scope: $scope.users = data;. The object doesn't contain Angular's tracking data, so the engine initiates everything from the beginning. The effect is annoying especially when you use CSS animations on elements being refreshed - everything is blinking, resetting, etc.

What I do to avoid it? I don't do $scope.data = data;, but I do update every single object of $scope.data by its new version from data (in your case).

Check out the code below. In my case, I fetch fresh list of servers, then I apply only changes.

$scope.servers = [];

$http.get('/panel/dashboard').then(function(res) {
    // find and upgrade servers
    for (var n in res.data.servers) {
        var s = res.data.servers[n];

        var l = get_server(s.id); // helper - get by ID from $scope.servers
        if (l) {
            $scope.servers.push({
                id: s.id, 
                name: s.name, 
                state: s.state
            });
        } else {
            // do update values only
            l.name = s.name;
            l.state = s.state;                
        }
    }

    // remember to remove old items that are in $scope.server and not in res.data
    // then sort data   
});

I hope it helps. The most important thing here is not 'how to solve' but understand 'how it works'.

Upvotes: 3

Jason
Jason

Reputation: 2887

Add the ng-cloak directive to your tag along with the following CSS:

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
  display: none !important;
}

More information can be found at Angular documentation -- https://docs.angularjs.org/api/ng/directive/ngCloak.

The documents states that the CSS is embedded in the angular.js file...but since I usually, as per best practices, load my JavaScript at the end of the page, the flicker still happens. Instead I just add the necessary CSS to my sites css file and that seems to work.

Upvotes: 0

Related Questions