VSO
VSO

Reputation: 12646

Angular - Some Attributes Need Explicit Binding to $scope, Others Don't?

Here is some code that works (glancing it is enough):

<div ng-repeat = "n in lotteryNumbers" ng-if="doShowExample">
    <input type="text" value = "{{lotteryNumbers[n]}}"></input>
</div>

<script>
angular.module('app', [])
        .controller('testCtrl', function($scope) {
            $scope.doShowExample = true;
            $scope.lotteryNumbers = [1,2,3,4,5,6,7,8,9,10];
        });
</script>

We see two attributes here that have values assigned:

ng-if="doShowExample" 

and

value = "{{lotteryNumbers[n]}}"

I don't really understand the logic behind one attribute's value needing to be put into curly braces(ng-model) to be bound and the other not. Why does it sometimes automatically know that your are looking for a variable rather than an explicit value?

Plnkr if you want it, but nothing interesting there. Just here in case I am wrong and you want to show me how.

Upvotes: 2

Views: 204

Answers (2)

PSL
PSL

Reputation: 123739

That is because value is not an angular directive but it is just an attribute of the element which can be assigned a value, it has not idea what an angular expression is. So providing an interpolation ('{{...}}') on an expression results in the assignment of the result of expression to the value of text box. But you rarely would need to do this if at all you need to provide value as is you could use angular directive ng-value as well.

   <input type="text" ng-value= "lotteryNumbers[n]"></input>

But most cases you need an ng-model for 2-way binding.

   <input type="text" ng-model= "lotteryNumbers[n]"></input>

So in short

{{AngularExpression_XYZ}} --> Value of AngularExpression_XYZ

When you see an angular directive that expects an expression you need to provide the expression itself, for ex - ng-if, ng-repeat, ng-show and many more..... But if you see something takes a value for example: ng-attr-xyou need to provide some value to it, which you do it via interpolation.

Now coming to what you have in your example you are doing it wrong by doing lotteryNumbers[n] where n from the ng-repeat expression ("n in lotteryNumbers") in your case is not the index but it is the value itself. But since you have array of numbers and you expect ng-model to work properly with the array of ng-repeat you may try using $index and also you would need to use track by expression itself since it will end up losing the focus on the textbox as the array gets updated.

<div ng-repeat = "n in lotteryNumbers track by $index" ng-if="doShowExample">
    <input type="text" ng-value = "lotteryNumbers[$index]"></input>
    <input type="text" ng-model = "lotteryNumbers[$index]"></input>
</div>

But in real usecase you should try to avoid this and bind it to array of objects in order to avoid such issues.

Upvotes: 4

Robin Gruschke
Robin Gruschke

Reputation: 234

In your example

ng-if

Is a angular directive that you pass a scope variable to.

value

Is a standard html attribute -> it cant take in scope variable. It can only handle "values" so you have to use {{var}}.

Upvotes: 1

Related Questions