Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
fix(ngModelOptions): initialize ngModelOptions in prelink
Browse files Browse the repository at this point in the history
Input controls require `ngModel` which in turn brings in the `ngModelOptions`
but since ngModel does this initialization in the post link function, the
order in which the directives are run is relevant.

Directives are sorted by priority and name but `ngModel`, `input` and `textarea`
have the same priority. It just happens that `textarea` is alphabetically
sorted and so linked before `ngModel` (unlike `input`).

This is a problem since inputs expect `ngModelController.$options`
to exist at post-link time and for `textarea` this has not happened.

This is solved easily by moving the initialization of `ngModel` to the
pre-link function.

Closes #7281
Closes #7292
  • Loading branch information
shahata authored and petebacondarwin committed May 4, 2014
1 parent e395170 commit fbf5ab8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
26 changes: 14 additions & 12 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -1973,22 +1973,24 @@ var ngModelDirective = function() {
return {
require: ['ngModel', '^?form', '^?ngModelOptions'],
controller: NgModelController,
link: function(scope, element, attr, ctrls) {
// notify others, especially parent forms
link: {
pre: function(scope, element, attr, ctrls) {
// Pass the ng-model-options to the ng-model controller
if (ctrls[2]) {
ctrls[0].$options = ctrls[2].$options;
}

var modelCtrl = ctrls[0],
formCtrl = ctrls[1] || nullFormCtrl;
// notify others, especially parent forms

formCtrl.$addControl(modelCtrl);
var modelCtrl = ctrls[0],
formCtrl = ctrls[1] || nullFormCtrl;

// Pass the ng-model-options to the ng-model controller
if ( ctrls[2] ) {
modelCtrl.$options = ctrls[2].$options;
}
formCtrl.$addControl(modelCtrl);

scope.$on('$destroy', function() {
formCtrl.$removeControl(modelCtrl);
});
scope.$on('$destroy', function() {
formCtrl.$removeControl(modelCtrl);
});
}
}
};
};
Expand Down
11 changes: 11 additions & 0 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,17 @@ describe('input', function() {
expect(scope.name).toEqual('a');
});

it('should allow overriding the model update trigger event on text areas', function() {
compileInput(
'<textarea ng-model="name" name="alias" '+
'ng-model-options="{ updateOn: \'blur\' }"'+
'/>');

changeInputValueTo('a');
expect(scope.name).toBeUndefined();
browserTrigger(inputElm, 'blur');
expect(scope.name).toEqual('a');
});

it('should bind the element to a list of events', function() {
compileInput(
Expand Down

0 comments on commit fbf5ab8

Please sign in to comment.