fix(forms): set state before emitting a value from ngModelChange (#21514)

Closes #21513.

PR Close #21514
This commit is contained in:
Philip Pham 2018-01-12 20:03:54 -08:00 committed by Miško Hevery
parent 0bcfae7cac
commit 9744a1c966
2 changed files with 42 additions and 1 deletions

View File

@ -99,9 +99,9 @@ function setUpBlurPipeline(control: FormControl, dir: NgControl): void {
}
function updateControl(control: FormControl, dir: NgControl): void {
dir.viewToModelUpdate(control._pendingValue);
if (control._pendingDirty) control.markAsDirty();
control.setValue(control._pendingValue, {emitModelToViewChange: false});
dir.viewToModelUpdate(control._pendingValue);
control._pendingChange = false;
}

View File

@ -1472,6 +1472,36 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat
expect(required.nativeElement.getAttribute('pattern')).toEqual(null);
}));
it('should update control status', fakeAsync(() => {
const fixture = initTest(NgModelChangeState);
const inputEl = fixture.debugElement.query(By.css('input'));
const inputNativeEl = inputEl.nativeElement;
const onNgModelChange = jasmine.createSpy('onNgModelChange');
fixture.componentInstance.onNgModelChange = onNgModelChange;
fixture.detectChanges();
tick();
expect(onNgModelChange).not.toHaveBeenCalled();
inputNativeEl.value = 'updated';
onNgModelChange.and.callFake((ngModel: NgModel) => {
expect(ngModel.invalid).toBe(true);
expect(ngModel.value).toBe('updated');
});
dispatchEvent(inputNativeEl, 'input');
expect(onNgModelChange).toHaveBeenCalled();
tick();
inputNativeEl.value = '333';
onNgModelChange.and.callFake((ngModel: NgModel) => {
expect(ngModel.invalid).toBe(false);
expect(ngModel.value).toBe('333');
});
dispatchEvent(inputNativeEl, 'input');
expect(onNgModelChange).toHaveBeenCalledTimes(2);
tick();
}));
});
describe('IME events', () => {
@ -1809,6 +1839,17 @@ class NgModelChangesForm {
log() { this.events.push('fired'); }
}
@Component({
selector: 'ng-model-change-state',
template: `
<input #ngModel="ngModel" ngModel [maxlength]="4"
(ngModelChange)="onNgModelChange(ngModel)">
`
})
class NgModelChangeState {
onNgModelChange = () => {};
}
function sortedClassList(el: HTMLElement) {
const l = getDOM().classList(el);
l.sort();