Hiroki
Hiroki

Reputation: 4163

AngularJS: Why is it (apparently) not necessary to declare a variable for ng-model?

Chances are other people are confused with this phoenomenon, so I post this question here.

HTML

<select 
    ng-model="cont.selectedItem" 
    ng-options="item.name for item in cont.lists.items" >
</select>

//"cont" indicates the controller. $scope is not used here

<span ng-click="addNewItem()">add</span>

JS

var instance = this;
instance.list = { ...item instances... };
instance.selectedItem;//Is it really necessary?

instance.addNewItem = function() {
  var  item = instance.selectedItem;
  ...
}

I used to believe that selectedItem, which is used in the ng-model, had to be declared as instance.selectedItem in JS, so that I could see which item was chosen in the ng-options.

However, I noticed that the var item in the addNewItem function gets the selected item, even when instance.selectedItem is commented out.

I went to the Angular's documentation, but I can't find out why.

Any advice will be appreciated.

Upvotes: 0

Views: 51

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

In your case you are defining a primitive type variable inside this context of controller, where by default that value of selectedItem is undefined as this has already been defined :) . In this when angular $parser sets an value. That operation is pretty straight forward. Behind the scene $parse do this thing for you.

Let me show you another example where you can see the actual magic made by $parse API. Suppose you wanted to set value for model.something where model object haven't been defined yet. Lets pass that value to $parse API and assign some value to it(see below code would help you to understand). The same thing will happen when you have assigned model.something value to ng-model directive. Whenever you change the value of ng-model value it assigns a value to underlying variable of its context.

Below is example that illustrate how $parse does work.

mainMod.controller('MainCtrl', ['$parse','$interpolate','$compile',
    function ($parse,$interpolate,$compile) {
         var vm = this; 

         //$parse
         vm.parse = $parse('model.something');
         //assigning value to `model.something` from `vm`
         //so the value is going to put inside `vm`
         //while assigning a value it check that value exists or not
         //if it isn't exist then it creates an value inside mentioned context
         //here context is `vm`(this)
         vm.parse.assign(vm, 'Pankaj'); 
         console.log(vm.model); //vm.model will have { something: 'Prakash' }
    }
]);

Upvotes: 2

Related Questions