Question

Here is a ngRepeat, that repeats Alerts for users. I want to show each alert one by one in a time period. I am using ngShow and a counter variable $scope.showedItem.

Template:

        <div class="container" >
            <div ng-repeat="headerNotification in headerNotification.list" ng-show="{{showedItem==$index}}">
                    <h3>{{headerNotification.getText()}}</h3>
                    <button ng-click="headerNotification.do()" class="btn btn-warning">{{headerNotification.getButtonText()}}</button>
            </div>
        </div>

Controller:

componentHeaderModule.controller('headerController', [
'$rootScope',
'$scope',
'componentHeaderNotification',
'$interval',
function ($rootScope, $scope, componentHeaderNotification, $interval)
{
    ...
    $scope.showedItem = 1;

    $interval(function(){
        $scope.showedItem++;
        if ($scope.showedItem > $scope.headerNotification.list.length)
            $scope.showedItem = 0;
    }, 5000);
}]);

When I am looking at DeveloperTool, I see that ng-show value is changing each 5 seconds, however, view is not refreshing, same alert is showing all the time. Even, items class is not changing.

What could be the problem? My understanding of two way binding is a big mistake?

Was it helpful?

Solution

ngShow evaluates an angular expression so you don't want the double curly braces inside it.

So inside:

<div ng-repeat="headerNotification in headerNotification.list" ng-show="{{showedItem==$index}}">

change this:

ng-show="{{showedItem==$index}}"

to this:

ng-show="showedItem==$index"

Angular does not, by default, put a $watch on attributes (which helps a lot with performance). This is why Angular expects you to pass in an expression for it to evaluate.

When you use the double curly braces inside an expression what happens is the expression inside the curlys is evaluated, just once, when the directive is linked in and that result (in your case true or false) is then passed in and used forever, never changing- even if the attribute's value changes, Angular never notices (since there's no $watch on it).

For instance if showedItem is equal to 0 when the linking is done, then the first ngRepeat entry is passed true while every other entry is passed false- resulting in what you're seeing, the ngShow never changing.

You want the expression to be evaluated every $digest cycle so you pass the expression in.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top