Tamás Sallai
Tamás Sallai

Reputation: 3365

AngularJS does not refresh ng-show when using only attributes

I have an AngularJS app, and just noticed that if I use ng-show and ng-click together and don't use function on the controller, then the ng-show is not working as expected.

So I have this:

<div ng-app ng-controller="Controller">
    <div ng-repeat="d in data">
        <button ng-show="showEdit!==d" ng-click="showEdit=d">{{d}}</button>
    </div>
</div>

With a controller:

function Controller($scope){
    $scope.data=[1,2,3]
}

Fiddle: http://jsfiddle.net/sashee/v6XrK/

And the buttons are disappearing when I click them, and never reappear.

If I change the view to this:

<div ng-app ng-controller="Controller">
    <div ng-repeat="d in data">
        <button ng-show="showEdit!==d" ng-click="show(d)">{{d}}</button>
    </div>
</div>

And the controller:

function Controller($scope){
    $scope.data=[1,2,3]

    $scope.show=function(d){
        $scope.showEdit=d;
    }
}

Fiddle: http://jsfiddle.net/sashee/UFGv4/

Everything works as expected. I think both versions should do exactly the same, but they aren't. What could be the difference or the explanation?

Upvotes: 1

Views: 1333

Answers (3)

Mr_Mig
Mr_Mig

Reputation: 783

Well, it's a bit quirky.

ng-repeat creates a new scope for each iterated element.

When you bind the click expression showEdit=d, you actually bind this expression to the Nth scope, created by the ng-repeat (hence the showEdit is located in scopeN).

When you simply use the function from the Controller, you change the showEdit field of the Controller's scope!

- Controller scope (showEdit in the 2nd example)
  - scope 1 (showEdit 1 in the 1st example)
  - scope 2 (showEdit 2 in the 1st example)
  ... 
  - scope N (showEdit N in the 1st example)

Upvotes: 0

Geoff Genz
Geoff Genz

Reputation: 2119

Please use spaces in your angular expressions.

The difference is that your ng-show and ng-click are in an ng-repeat. Each ng-repeat element has its own scope. So when you do the following:

ng-click="showEdit=d"

You are creating a new value of showEdit on the anonymous ng-repeat scope, not the scope that your controller knows about. Other ng-repeat elements know nothing about it, so your conditional ng-show="showEdit!==d" reflects the value that you just set, not the value of showEdit from your controller.

Upvotes: 0

tymeJV
tymeJV

Reputation: 104795

Simple, ng-repeat creates it's own scope, so when you do showEdit=d inside your ng-repeat -- showEdit is limited to the scope of the current repeater. Your variable gets set and your button disappears.

In the example where you call the function, you have a variable $scope.showEdit -- well that variable isn't limited to the repeat scope, so you will always have two buttons showing since showEdit is being assigned differently due to each click.

Upvotes: 3

Related Questions