6

Below is a pretty straightforward setup for a form drop down list. However, the on-change event refuses to fire... unless it's changed to ng-change.

This had me stuck for about an hour, since we use the same setup elsewhere in our site (i.e. model property/list/on-change directive) without fail.

I'm wondering what the difference is between on-change and ng-change and why one works in this instance and the other doesn't?

View

<select id="grArchive"
        name="grArchive"
        class="form-control"
        options="userList"
        ng-model="selectedUser"
        ng-options="user as user.name for user in userList"
        on-change="showSelected()">
</select> 

Controller

scope.selectedUser = {};
scope.userList = [];

scope.showSelected = function(){
    scope.columns = addColumns;
};

var loadUserList = function(data){
    scope.userList = $.map(data, function(item){
            return {id: item.id, name: item.firstName + ' ' + item.lastName};
        });
}

Just in case: the user drop down populates as expected (screen shot below)

enter image description here

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
NealR
  • 10,189
  • 61
  • 159
  • 299

1 Answers1

7

ng-change

ng-change is a directive provided by Angular core API which internally registers an expression to be called when any change happens in $viewValue of ng-model variable (here is the code); assign it an expression such as myFunction(). That provided expression will evaluate inside the underlying controller scope. After calling an expression it runs a digest cycle to make sure bindings are updated on the view. Besides ng-change there are other directives used for events, like ng-focus,ng-mousedown,ng-submit, ng-blur, etc. Here is a list of such directives

on-change

It is a way of calling a JavaScript function on change of input element value. It will search for the function which is globally available in context (obviously it will not call the function registered in angular controller) and evaluate it.

Juan Carlos Ramirez
  • 2,054
  • 1
  • 7
  • 22
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Is funny how people say 'old way'. Which is the new way then? – Misters Jul 14 '16 at 16:16
  • @Misters Oh, my bad, I didn't added it intentionally, I remove `old` word. :( – Pankaj Parkar Jul 14 '16 at 16:18
  • 1
    https://github.com/angular/angular.js/blob/a4e60cb6970d8b6fa9e0af4b9f881ee3ba7fdc99/src/ng/directive/ngChange.js it does not bind any event itself – Petr Averyanov Jul 14 '16 at 16:45
  • @PetrAveryanov You are partially correct, Thanks for heads up. Actually other events are handled in that way I talked, [here](https://github.com/angular/angular.js/blob/a4e60cb6970d8b6fa9e0af4b9f881ee3ba7fdc99/src/ng/directive/ngEventDirs.js#L49) you can see. – Pankaj Parkar Jul 15 '16 at 07:44
  • The thing I said partial because, If you look at how `$viewChangeListner` call the registered listner, then you will understand indirectly it does call the register listener on `change` event. Basically there in one `input` change event, which does call, $setViewValue method to update `$viewValue`, which call one method to set `$viewValue` to `$modelValue`, between that it called `$commitValue` method to make changes in `$modelValue` in that method only it call listeners of `$viewChangeListner`. – Pankaj Parkar Jul 15 '16 at 07:44
  • I'm still not getting the specifics of what makes them different. Does `on-change` listens for a change in the HTML input element, but doesn't ng-change do the same, by proxy, by listening for a change in the model property via the HTML input element? – NealR Jul 15 '16 at 12:44
  • @NealR `ng-change` does get fired when underlying `ng-model` value gets changed. Behind the scene angular maintain two value for each value those are [`$viewValue` & `$modelValue`](http://stackoverflow.com/questions/19383812/whats-the-difference-between-ngmodel-modelvalue-and-ngmodel-viewvalue), so when `$modelValue` gets change only that time it fires change event by [this line](https://github.com/angular/angular.js/blob/a4e60cb6970d8b6fa9e0af4b9f881ee3ba7fdc99/src/ng/directive/ngChange.js#L75) – Pankaj Parkar Jul 15 '16 at 12:53