fix(forms): updateOn should check if change occurred (#20358)
Fixes #20259. PR Close #20358
This commit is contained in:

committed by
Miško Hevery

parent
365712e2f0
commit
69c53c3e03
@ -484,6 +484,64 @@ export function main() {
|
||||
sub.unsubscribe();
|
||||
}));
|
||||
|
||||
it('should not fire ngModelChange event on blur unless value has changed', fakeAsync(() => {
|
||||
const fixture = initTest(NgModelChangesForm);
|
||||
fixture.componentInstance.name = 'Carson';
|
||||
fixture.componentInstance.options = {updateOn: 'blur'};
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual([], 'Expected ngModelChanges not to fire.');
|
||||
|
||||
const input = fixture.debugElement.query(By.css('input')).nativeElement;
|
||||
dispatchEvent(input, 'blur');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual([], 'Expected ngModelChanges not to fire if value unchanged.');
|
||||
|
||||
input.value = 'Carson';
|
||||
dispatchEvent(input, 'input');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual([], 'Expected ngModelChanges not to fire on input.');
|
||||
|
||||
dispatchEvent(input, 'blur');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired'], 'Expected ngModelChanges to fire once blurred if value changed.');
|
||||
|
||||
dispatchEvent(input, 'blur');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired'],
|
||||
'Expected ngModelChanges not to fire again on blur unless value changed.');
|
||||
|
||||
input.value = 'Bess';
|
||||
dispatchEvent(input, 'input');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(['fired'], 'Expected ngModelChanges not to fire on input after blur.');
|
||||
|
||||
dispatchEvent(input, 'blur');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired', 'fired'],
|
||||
'Expected ngModelChanges to fire again on blur if value changed.');
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('submit', () => {
|
||||
@ -764,6 +822,62 @@ export function main() {
|
||||
sub.unsubscribe();
|
||||
}));
|
||||
|
||||
it('should not fire ngModelChange event on submit unless value has changed',
|
||||
fakeAsync(() => {
|
||||
const fixture = initTest(NgModelChangesForm);
|
||||
fixture.componentInstance.name = 'Carson';
|
||||
fixture.componentInstance.options = {updateOn: 'submit'};
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
const formEl = fixture.debugElement.query(By.css('form')).nativeElement;
|
||||
dispatchEvent(formEl, 'submit');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual([], 'Expected ngModelChanges not to fire if value unchanged.');
|
||||
|
||||
const input = fixture.debugElement.query(By.css('input')).nativeElement;
|
||||
input.value = 'Carson';
|
||||
dispatchEvent(input, 'input');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual([], 'Expected ngModelChanges not to fire on input.');
|
||||
|
||||
dispatchEvent(formEl, 'submit');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired'], 'Expected ngModelChanges to fire once submitted if value changed.');
|
||||
|
||||
dispatchEvent(formEl, 'submit');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired'],
|
||||
'Expected ngModelChanges not to fire again on submit unless value changed.');
|
||||
|
||||
input.value = 'Bess';
|
||||
dispatchEvent(input, 'input');
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(['fired'], 'Expected ngModelChanges not to fire on input after submit.');
|
||||
|
||||
dispatchEvent(formEl, 'submit');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.events)
|
||||
.toEqual(
|
||||
['fired', 'fired'],
|
||||
'Expected ngModelChanges to fire again on submit if value changed.');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('ngFormOptions', () => {
|
||||
@ -1670,6 +1784,23 @@ class NgAsyncValidator implements AsyncValidator {
|
||||
class NgModelAsyncValidation {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ng-model-changes-form',
|
||||
template: `
|
||||
<form>
|
||||
<input name="async" [ngModel]="name" (ngModelChange)="log()"
|
||||
[ngModelOptions]="options">
|
||||
</form>
|
||||
`
|
||||
})
|
||||
class NgModelChangesForm {
|
||||
name: string;
|
||||
events: string[] = [];
|
||||
options: any;
|
||||
|
||||
log() { this.events.push('fired'); }
|
||||
}
|
||||
|
||||
function sortedClassList(el: HTMLElement) {
|
||||
const l = getDOM().classList(el);
|
||||
l.sort();
|
||||
|
Reference in New Issue
Block a user