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

Commit fbf5ab8

Browse files
shahatapetebacondarwin
authored andcommitted
fix(ngModelOptions): initialize ngModelOptions in prelink
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
1 parent e395170 commit fbf5ab8

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

src/ng/directive/input.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -1973,22 +1973,24 @@ var ngModelDirective = function() {
19731973
return {
19741974
require: ['ngModel', '^?form', '^?ngModelOptions'],
19751975
controller: NgModelController,
1976-
link: function(scope, element, attr, ctrls) {
1977-
// notify others, especially parent forms
1976+
link: {
1977+
pre: function(scope, element, attr, ctrls) {
1978+
// Pass the ng-model-options to the ng-model controller
1979+
if (ctrls[2]) {
1980+
ctrls[0].$options = ctrls[2].$options;
1981+
}
19781982

1979-
var modelCtrl = ctrls[0],
1980-
formCtrl = ctrls[1] || nullFormCtrl;
1983+
// notify others, especially parent forms
19811984

1982-
formCtrl.$addControl(modelCtrl);
1985+
var modelCtrl = ctrls[0],
1986+
formCtrl = ctrls[1] || nullFormCtrl;
19831987

1984-
// Pass the ng-model-options to the ng-model controller
1985-
if ( ctrls[2] ) {
1986-
modelCtrl.$options = ctrls[2].$options;
1987-
}
1988+
formCtrl.$addControl(modelCtrl);
19881989

1989-
scope.$on('$destroy', function() {
1990-
formCtrl.$removeControl(modelCtrl);
1991-
});
1990+
scope.$on('$destroy', function() {
1991+
formCtrl.$removeControl(modelCtrl);
1992+
});
1993+
}
19921994
}
19931995
};
19941996
};

test/ng/directive/inputSpec.js

+11
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,17 @@ describe('input', function() {
642642
expect(scope.name).toEqual('a');
643643
});
644644

645+
it('should allow overriding the model update trigger event on text areas', function() {
646+
compileInput(
647+
'<textarea ng-model="name" name="alias" '+
648+
'ng-model-options="{ updateOn: \'blur\' }"'+
649+
'/>');
650+
651+
changeInputValueTo('a');
652+
expect(scope.name).toBeUndefined();
653+
browserTrigger(inputElm, 'blur');
654+
expect(scope.name).toEqual('a');
655+
});
645656

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

0 commit comments

Comments
 (0)