feat(ngModelOptions): add debounce catch-all + allow debouncing 'default' only
Closes #15411 Closes #16335 BREAKING CHANGE: the 'default' key in 'debounce' now only debounces the default event, i.e. the event that is added as an update trigger by the different input directives automatically. Previously, it also applied to other update triggers defined in 'updateOn' that did not have a corresponding key in the 'debounce'. This behavior is now supported via a special wildcard / catch-all key: '*'. See the following example: Pre-1.7: 'mouseup' is also debounced by 500 milliseconds because 'default' is applied: ``` ng-model-options="{ updateOn: 'default blur mouseup', debounce: { 'default': 500, 'blur': 0 } } ``` 1.7: The pre-1.7 behavior can be re-created by setting '*' as a catch-all debounce value: ``` ng-model-options="{ updateOn: 'default blur mouseup', debounce: { '*': 500, 'blur': 0 } } ``` In contrast, when only 'default' is used, 'blur' and 'mouseup' are not debounced: ``` ng-model-options="{ updateOn: 'default blur mouseup', debounce: { 'default': 500 } } ```
This commit is contained in:
@@ -838,8 +838,12 @@ NgModelController.prototype = {
|
||||
|
||||
if (isNumber(debounceDelay[trigger])) {
|
||||
debounceDelay = debounceDelay[trigger];
|
||||
} else if (isNumber(debounceDelay['default'])) {
|
||||
} else if (isNumber(debounceDelay['default']) &&
|
||||
this.$options.getOption('updateOn').indexOf(trigger) === -1
|
||||
) {
|
||||
debounceDelay = debounceDelay['default'];
|
||||
} else if (isNumber(debounceDelay['*'])) {
|
||||
debounceDelay = debounceDelay['*'];
|
||||
}
|
||||
|
||||
this.$$timeout.cancel(this.$$pendingDebounce);
|
||||
|
||||
@@ -321,6 +321,14 @@ defaultModelOptions = new ModelOptions({
|
||||
* debounce: { 'default': 500, 'blur': 0 }
|
||||
* }"
|
||||
* ```
|
||||
* You can use the `*` key to specify a debounce value that applies to all events that are not
|
||||
* specifically listed. In the following example, `mouseup` would have a debounce delay of 1000:
|
||||
* ```
|
||||
* ng-model-options="{
|
||||
* updateOn: 'default blur mouseup',
|
||||
* debounce: { 'default': 500, 'blur': 0, '*': 1000 }
|
||||
* }"
|
||||
* ```
|
||||
* - `allowInvalid`: boolean value which indicates that the model can be set with values that did
|
||||
* not validate correctly instead of the default behavior of setting the model to undefined.
|
||||
* - `getterSetter`: boolean value which determines whether or not to treat functions bound to
|
||||
|
||||
@@ -498,9 +498,41 @@ describe('ngModelOptions', function() {
|
||||
|
||||
helper.changeInputValueTo('c');
|
||||
browserTrigger(helper.inputElm, 'mouseup');
|
||||
// counter-intuitively `default` in `debounce` is a catch-all
|
||||
// `default` in `debounce` only affects the event triggers that are not defined in updateOn
|
||||
expect($rootScope.name).toEqual('c');
|
||||
});
|
||||
|
||||
|
||||
it('should use the value of * to debounce all unspecified events',
|
||||
function() {
|
||||
var inputElm = helper.compileInput(
|
||||
'<input type="text" ng-model="name" name="alias" ' +
|
||||
'ng-model-options="{' +
|
||||
'updateOn: \'default blur mouseup\', ' +
|
||||
'debounce: { default: 10000, blur: 5000, \'*\': 15000 }' +
|
||||
'}"' +
|
||||
'/>');
|
||||
|
||||
helper.changeInputValueTo('a');
|
||||
expect($rootScope.name).toBeUndefined();
|
||||
$timeout.flush(6000);
|
||||
expect($rootScope.name).toBeUndefined();
|
||||
$timeout.flush(4000);
|
||||
expect($rootScope.name).toEqual('a');
|
||||
|
||||
helper.changeInputValueTo('b');
|
||||
browserTrigger(inputElm, 'blur');
|
||||
$timeout.flush(4000);
|
||||
expect($rootScope.name).toEqual('a');
|
||||
$timeout.flush(2000);
|
||||
expect($rootScope.name).toEqual('b');
|
||||
$timeout.flush(10000);
|
||||
|
||||
helper.changeInputValueTo('c');
|
||||
browserTrigger(helper.inputElm, 'mouseup');
|
||||
expect($rootScope.name).toEqual('b');
|
||||
$timeout.flush(10000); // flush default
|
||||
expect($rootScope.name).toEqual('b');
|
||||
$timeout.flush(5000);
|
||||
expect($rootScope.name).toEqual('c');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user