fix(forms): number input fires valueChanges twice. (#36087)
Prior to this commit, number input fields would to fire valueChanges twice: once for `input` events when typing and second for the `change` event when the field lost focus (both events happen at once when using the increment and decrement buttons on the number field). Fixes #12540 BREAKING CHANGE: Number inputs no longer listen to the `change` event. * Tests which trigger `change` events need to be updated to trigger `input` events instead. * The `change` event was in place to support IE9, as we found that `input` events were not fired with backspace or cut actions. If you need to maintain IE9 support, you will need to add a change event listener to number inputs and call the `onChange` method of `NumberValueAccessor` manually. * Lastly, old versions of WebDriver would synthetically trigger the `change` event on `WebElement.clear` and `WebElement.sendKeys`. If you are using an old version of WebDriver, you may need to update tests to ensure `input` events are triggered. For example, you could use `element.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.BACK_SPACE);` in place of `element.clear()`. PR Close #12540 PR Close #36087
This commit is contained in:
parent
f7815cf96d
commit
97d6d909e7
|
@ -43,11 +43,7 @@ export const NUMBER_VALUE_ACCESSOR: any = {
|
|||
@Directive({
|
||||
selector:
|
||||
'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
|
||||
host: {
|
||||
'(change)': 'onChange($event.target.value)',
|
||||
'(input)': 'onChange($event.target.value)',
|
||||
'(blur)': 'onTouched()'
|
||||
},
|
||||
host: {'(input)': 'onChange($event.target.value)', '(blur)': 'onTouched()'},
|
||||
providers: [NUMBER_VALUE_ACCESSOR]
|
||||
})
|
||||
export class NumberValueAccessor implements ControlValueAccessor {
|
||||
|
|
|
@ -149,6 +149,23 @@ import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util'
|
|||
expect(control.value).toEqual(0);
|
||||
});
|
||||
|
||||
it('should ignore the change event', () => {
|
||||
const fixture = initTest(FormControlNumberInput);
|
||||
const control = new FormControl();
|
||||
fixture.componentInstance.control = control;
|
||||
fixture.detectChanges();
|
||||
|
||||
control.valueChanges.subscribe({
|
||||
next: (value) => {
|
||||
throw 'Input[number] should not react to change event';
|
||||
}
|
||||
});
|
||||
const input = fixture.debugElement.query(By.css('input'));
|
||||
|
||||
input.nativeElement.value = '5';
|
||||
dispatchEvent(input.nativeElement, 'change');
|
||||
});
|
||||
|
||||
it('when value is cleared programmatically', () => {
|
||||
const fixture = initTest(FormControlNumberInput);
|
||||
const control = new FormControl(10);
|
||||
|
|
Loading…
Reference in New Issue