Skip to content

Commit d44e5b9

Browse files
feat(ngModelOptions): allow options to be inherited from ancestor ngModelOptions
Previously, you had to apply the complete set of `ngModelOptions` at every point where you might want to modify just one or two settings. This change allows more general settings to be applied nearer to the top of the DOM and then for more specific settings to override those general settings further down in the DOM. To prevent unwanted inheritance you must opt-in on a case by case basis: * To inherit as single property you simply provide the special value `"$inherit"`. * To inherit all properties not specified locally then include a property `"*": "$inherit"`. Closes angular#10922 Closes angular#15389 BREAKING CHANGE: The programmatic API for `ngModelOptions` has changed. You must now read options via the `ngModelController.getOption(name)` method, rather than accessing the option directly as a property of the `ngModelContoller.$options` object. This does not affect the usage in templates and only affects custom directives that might have been reading options for their own purposes.
1 parent 2590e94 commit d44e5b9

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

src/ng/directive/ngModelOptions.js

+14-6
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,21 @@ ModelOptions.prototype = {
4747
inheritAll = true;
4848
} else {
4949
options[key] = this.$$options[key];
50+
// `updateOn` is special so we must also inherit the `updateOnDefault` option
51+
if (key === 'updateOn') {
52+
options.updateOnDefault = this.$$options.updateOnDefault;
53+
}
54+
}
55+
} else {
56+
if (key === 'updateOn') {
57+
// If the `updateOn` property contains the `default` event then we have to remove
58+
// it from the event list and set the `updateOnDefault` flag.
59+
options.updateOnDefault = false;
60+
options[key] = trim(option.replace(DEFAULT_REGEXP, function() {
61+
options.updateOnDefault = true;
62+
return ' ';
63+
}));
5064
}
51-
} else if (key === 'updateOn') {
52-
options.updateOnDefault = false;
53-
options[key] = trim(option.replace(DEFAULT_REGEXP, function() {
54-
options.updateOnDefault = true;
55-
return ' ';
56-
}));
5765
}
5866
}, this);
5967

test/ng/directive/ngModelOptionsSpec.js

+26-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
generateInputCompilerHelper: false,
55
$defaultModelOptions: false
66
*/
7-
describe('ngModelOptions', function() {
7+
fdescribe('ngModelOptions', function() {
88

99
describe('$defaultModelOptions', function() {
1010
it('should provide default values', function() {
@@ -180,6 +180,31 @@ describe('ngModelOptions', function() {
180180
});
181181

182182

183+
it('should `updateOnDefault` as well if we have `updateOn: "$inherit"`', function() {
184+
var container = $compile(
185+
'<div ng-model-options="{updateOn: \'keyup\'}">' +
186+
'<input ng-model-options="{\'updateOn\': \'$inherit\'}">' +
187+
'<div ng-model-options="{updateOn: \'default blur\'}">' +
188+
'<input ng-model-options="{\'updateOn\': \'$inherit\'}">' +
189+
'</div>' +
190+
'</div>')($rootScope);
191+
192+
var input1 = container.find('input').eq(0);
193+
var inputOptions1 = input1.controller('ngModelOptions').$options;
194+
195+
expect(inputOptions1.getOption('updateOn')).toEqual('keyup');
196+
expect(inputOptions1.getOption('updateOnDefault')).toEqual(false);
197+
198+
var input2 = container.find('input').eq(1);
199+
var inputOptions2 = input2.controller('ngModelOptions').$options;
200+
201+
expect(inputOptions2.getOption('updateOn')).toEqual('blur');
202+
expect(inputOptions2.getOption('updateOnDefault')).toEqual(true);
203+
204+
dealoc(container);
205+
});
206+
207+
183208
it('should make a copy of the options object', function() {
184209
$rootScope.options = {updateOn: 'default'};
185210
var inputElm = helper.compileInput(

0 commit comments

Comments
 (0)