feat(forms): Added emitEvent to AbstractControl methods (#11949)

* feat(forms): Added emitEvent to AbstractControl methods

* style(forms): unified named parameter
This commit is contained in:
Florian Kinder 2016-10-19 18:54:54 +02:00 committed by Alex Rickabaugh
parent 592f40aa9c
commit b9fc090143
5 changed files with 127 additions and 43 deletions

View File

@ -249,7 +249,7 @@ export abstract class AbstractControl {
this._touched = true; this._touched = true;
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsTouched({onlySelf: onlySelf}); this._parent.markAsTouched({onlySelf});
} }
} }
@ -267,7 +267,7 @@ export abstract class AbstractControl {
(control: AbstractControl) => { control.markAsUntouched({onlySelf: true}); }); (control: AbstractControl) => { control.markAsUntouched({onlySelf: true}); });
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent._updateTouched({onlySelf: onlySelf}); this._parent._updateTouched({onlySelf});
} }
} }
@ -282,7 +282,7 @@ export abstract class AbstractControl {
this._pristine = false; this._pristine = false;
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsDirty({onlySelf: onlySelf}); this._parent.markAsDirty({onlySelf});
} }
} }
@ -299,7 +299,7 @@ export abstract class AbstractControl {
this._forEachChild((control: AbstractControl) => { control.markAsPristine({onlySelf: true}); }); this._forEachChild((control: AbstractControl) => { control.markAsPristine({onlySelf: true}); });
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent._updatePristine({onlySelf: onlySelf}); this._parent._updatePristine({onlySelf});
} }
} }
@ -311,7 +311,7 @@ export abstract class AbstractControl {
this._status = PENDING; this._status = PENDING;
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent.markAsPending({onlySelf: onlySelf}); this._parent.markAsPending({onlySelf});
} }
} }
@ -348,7 +348,7 @@ export abstract class AbstractControl {
enable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void { enable({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
this._status = VALID; this._status = VALID;
this._forEachChild((control: AbstractControl) => { control.enable({onlySelf: true}); }); this._forEachChild((control: AbstractControl) => { control.enable({onlySelf: true}); });
this.updateValueAndValidity({onlySelf: true, emitEvent: emitEvent}); this.updateValueAndValidity({onlySelf: true, emitEvent});
this._updateAncestors(onlySelf); this._updateAncestors(onlySelf);
this._onDisabledChange.forEach((changeFn) => changeFn(false)); this._onDisabledChange.forEach((changeFn) => changeFn(false));
@ -407,7 +407,7 @@ export abstract class AbstractControl {
} }
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); this._parent.updateValueAndValidity({onlySelf, emitEvent});
} }
} }
@ -428,8 +428,8 @@ export abstract class AbstractControl {
this._status = PENDING; this._status = PENDING;
this._cancelExistingSubscription(); this._cancelExistingSubscription();
var obs = toObservable(this.asyncValidator(this)); var obs = toObservable(this.asyncValidator(this));
this._asyncValidationSubscription = obs.subscribe( this._asyncValidationSubscription =
{next: (res: {[key: string]: any}) => this.setErrors(res, {emitEvent: emitEvent})}); obs.subscribe({next: (res: {[key: string]: any}) => this.setErrors(res, {emitEvent})});
} }
} }
@ -582,7 +582,7 @@ export abstract class AbstractControl {
this._pristine = !this._anyControlsDirty(); this._pristine = !this._anyControlsDirty();
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent._updatePristine({onlySelf: onlySelf}); this._parent._updatePristine({onlySelf});
} }
} }
@ -591,7 +591,7 @@ export abstract class AbstractControl {
this._touched = this._anyControlsTouched(); this._touched = this._anyControlsTouched();
if (isPresent(this._parent) && !onlySelf) { if (isPresent(this._parent) && !onlySelf) {
this._parent._updateTouched({onlySelf: onlySelf}); this._parent._updateTouched({onlySelf});
} }
} }
@ -694,7 +694,7 @@ export class FormControl extends AbstractControl {
if (this._onChange.length && emitModelToViewChange) { if (this._onChange.length && emitModelToViewChange) {
this._onChange.forEach((changeFn) => changeFn(this._value, emitViewToModelChange)); this._onChange.forEach((changeFn) => changeFn(this._value, emitViewToModelChange));
} }
this.updateValueAndValidity({onlySelf: onlySelf, emitEvent: emitEvent}); this.updateValueAndValidity({onlySelf, emitEvent});
} }
/** /**
@ -741,11 +741,12 @@ export class FormControl extends AbstractControl {
* console.log(this.control.status); // 'DISABLED' * console.log(this.control.status); // 'DISABLED'
* ``` * ```
*/ */
reset(formState: any = null, {onlySelf}: {onlySelf?: boolean} = {}): void { reset(formState: any = null, {onlySelf, emitEvent}: {onlySelf?: boolean,
emitEvent?: boolean} = {}): void {
this._applyFormState(formState); this._applyFormState(formState);
this.markAsPristine({onlySelf}); this.markAsPristine({onlySelf});
this.markAsUntouched({onlySelf}); this.markAsUntouched({onlySelf});
this.setValue(this._value, {onlySelf}); this.setValue(this._value, {onlySelf, emitEvent});
} }
/** /**
@ -938,13 +939,15 @@ export class FormGroup extends AbstractControl {
* *
* ``` * ```
*/ */
setValue(value: {[key: string]: any}, {onlySelf}: {onlySelf?: boolean} = {}): void { setValue(
value: {[key: string]: any},
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
this._checkAllValuesPresent(value); this._checkAllValuesPresent(value);
Object.keys(value).forEach(name => { Object.keys(value).forEach(name => {
this._throwIfControlMissing(name); this._throwIfControlMissing(name);
this.controls[name].setValue(value[name], {onlySelf: true}); this.controls[name].setValue(value[name], {onlySelf: true, emitEvent});
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
} }
/** /**
@ -968,13 +971,15 @@ export class FormGroup extends AbstractControl {
* *
* ``` * ```
*/ */
patchValue(value: {[key: string]: any}, {onlySelf}: {onlySelf?: boolean} = {}): void { patchValue(
value: {[key: string]: any},
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
Object.keys(value).forEach(name => { Object.keys(value).forEach(name => {
if (this.controls[name]) { if (this.controls[name]) {
this.controls[name].patchValue(value[name], {onlySelf: true}); this.controls[name].patchValue(value[name], {onlySelf: true, emitEvent});
} }
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
} }
/** /**
@ -1009,13 +1014,14 @@ export class FormGroup extends AbstractControl {
* console.log(this.form.get('first').status); // 'DISABLED' * console.log(this.form.get('first').status); // 'DISABLED'
* ``` * ```
*/ */
reset(value: any = {}, {onlySelf}: {onlySelf?: boolean} = {}): void { reset(value: any = {}, {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {
this._forEachChild((control: AbstractControl, name: string) => { this._forEachChild((control: AbstractControl, name: string) => {
control.reset(value[name], {onlySelf: true}); control.reset(value[name], {onlySelf: true, emitEvent});
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
this._updatePristine({onlySelf: onlySelf}); this._updatePristine({onlySelf});
this._updateTouched({onlySelf: onlySelf}); this._updateTouched({onlySelf});
} }
/** /**
@ -1240,13 +1246,14 @@ export class FormArray extends AbstractControl {
* console.log(arr.value); // ['Nancy', 'Drew'] * console.log(arr.value); // ['Nancy', 'Drew']
* ``` * ```
*/ */
setValue(value: any[], {onlySelf}: {onlySelf?: boolean} = {}): void { setValue(value: any[], {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {
this._checkAllValuesPresent(value); this._checkAllValuesPresent(value);
value.forEach((newValue: any, index: number) => { value.forEach((newValue: any, index: number) => {
this._throwIfControlMissing(index); this._throwIfControlMissing(index);
this.at(index).setValue(newValue, {onlySelf: true}); this.at(index).setValue(newValue, {onlySelf: true, emitEvent});
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
} }
/** /**
@ -1269,13 +1276,14 @@ export class FormArray extends AbstractControl {
* console.log(arr.value); // ['Nancy', null] * console.log(arr.value); // ['Nancy', null]
* ``` * ```
*/ */
patchValue(value: any[], {onlySelf}: {onlySelf?: boolean} = {}): void { patchValue(value: any[], {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {
value.forEach((newValue: any, index: number) => { value.forEach((newValue: any, index: number) => {
if (this.at(index)) { if (this.at(index)) {
this.at(index).patchValue(newValue, {onlySelf: true}); this.at(index).patchValue(newValue, {onlySelf: true, emitEvent});
} }
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
} }
/** /**
@ -1309,13 +1317,14 @@ export class FormArray extends AbstractControl {
* console.log(this.arr.get(0).status); // 'DISABLED' * console.log(this.arr.get(0).status); // 'DISABLED'
* ``` * ```
*/ */
reset(value: any = [], {onlySelf}: {onlySelf?: boolean} = {}): void { reset(value: any = [], {onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
void {
this._forEachChild((control: AbstractControl, index: number) => { this._forEachChild((control: AbstractControl, index: number) => {
control.reset(value[index], {onlySelf: true}); control.reset(value[index], {onlySelf: true, emitEvent});
}); });
this.updateValueAndValidity({onlySelf: onlySelf}); this.updateValueAndValidity({onlySelf, emitEvent});
this._updatePristine({onlySelf: onlySelf}); this._updatePristine({onlySelf});
this._updateTouched({onlySelf: onlySelf}); this._updateTouched({onlySelf});
} }
/** /**

View File

@ -172,6 +172,16 @@ export function main() {
expect(logger).toEqual(['control1', 'control2', 'array', 'form']); expect(logger).toEqual(['control1', 'control2', 'array', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c2.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.setValue(['one', 'two'], {emitEvent: false});
tick();
}));
it('should emit one statusChange event per control', () => { it('should emit one statusChange event per control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
a.statusChanges.subscribe(() => logger.push('array')); a.statusChanges.subscribe(() => logger.push('array'));
@ -277,6 +287,16 @@ export function main() {
expect(logger).toEqual(['control1', 'array', 'form']); expect(logger).toEqual(['control1', 'array', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c2.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.patchValue(['one', 'two'], {emitEvent: false});
tick();
}));
it('should emit one statusChange event per control', () => { it('should emit one statusChange event per control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
a.statusChanges.subscribe(() => logger.push('array')); a.statusChanges.subscribe(() => logger.push('array'));
@ -478,6 +498,17 @@ export function main() {
expect(logger).toEqual(['control1', 'control2', 'array', 'form']); expect(logger).toEqual(['control1', 'control2', 'array', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c2.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c3.valueChanges.subscribe((value) => { throw 'Should not happen'; });
a.reset([], {emitEvent: false});
tick();
}));
it('should emit one statusChange event per reset control', () => { it('should emit one statusChange event per reset control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
a.statusChanges.subscribe(() => logger.push('array')); a.statusChanges.subscribe(() => logger.push('array'));

View File

@ -555,6 +555,16 @@ export function main() {
expect(logger).toEqual(['control1', 'group']); expect(logger).toEqual(['control1', 'group']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
g.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c2.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.reset(null, {emitEvent: false});
tick();
}));
it('should emit one statusChange event per reset control', () => { it('should emit one statusChange event per reset control', () => {
g.statusChanges.subscribe(() => logger.push('group')); g.statusChanges.subscribe(() => logger.push('group'));
c.statusChanges.subscribe(() => logger.push('control1')); c.statusChanges.subscribe(() => logger.push('control1'));

View File

@ -236,6 +236,15 @@ export function main() {
expect(logger).toEqual(['control1', 'control2', 'group', 'form']); expect(logger).toEqual(['control1', 'control2', 'group', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.setValue({'one': 'one', 'two': 'two'}, {emitEvent: false});
tick();
}));
it('should emit one statusChange event per control', () => { it('should emit one statusChange event per control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
g.statusChanges.subscribe(() => logger.push('group')); g.statusChanges.subscribe(() => logger.push('group'));
@ -341,6 +350,15 @@ export function main() {
expect(logger).toEqual(['control1', 'group', 'form']); expect(logger).toEqual(['control1', 'group', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.patchValue({'one': 'one', 'two': 'two'}, {emitEvent: false});
tick();
}));
it('should emit one statusChange event per control', () => { it('should emit one statusChange event per control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
g.statusChanges.subscribe(() => logger.push('group')); g.statusChanges.subscribe(() => logger.push('group'));
@ -541,6 +559,15 @@ export function main() {
expect(logger).toEqual(['control1', 'control2', 'group', 'form']); expect(logger).toEqual(['control1', 'control2', 'group', 'form']);
}); });
it('should not fire an event when explicitly specified', fakeAsync(() => {
form.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.valueChanges.subscribe((value) => { throw 'Should not happen'; });
c.valueChanges.subscribe((value) => { throw 'Should not happen'; });
g.reset({}, {emitEvent: false});
tick();
}));
it('should emit one statusChange event per reset control', () => { it('should emit one statusChange event per reset control', () => {
form.statusChanges.subscribe(() => logger.push('form')); form.statusChanges.subscribe(() => logger.push('form'));
g.statusChanges.subscribe(() => logger.push('group')); g.statusChanges.subscribe(() => logger.push('group'));

View File

@ -161,17 +161,20 @@ export declare class FormArray extends AbstractControl {
at(index: number): AbstractControl; at(index: number): AbstractControl;
getRawValue(): any[]; getRawValue(): any[];
insert(index: number, control: AbstractControl): void; insert(index: number, control: AbstractControl): void;
patchValue(value: any[], {onlySelf}?: { patchValue(value: any[], {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
push(control: AbstractControl): void; push(control: AbstractControl): void;
removeAt(index: number): void; removeAt(index: number): void;
reset(value?: any, {onlySelf}?: { reset(value?: any, {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
setControl(index: number, control: AbstractControl): void; setControl(index: number, control: AbstractControl): void;
setValue(value: any[], {onlySelf}?: { setValue(value: any[], {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
} }
@ -210,8 +213,9 @@ export declare class FormControl extends AbstractControl {
}): void; }): void;
registerOnChange(fn: Function): void; registerOnChange(fn: Function): void;
registerOnDisabledChange(fn: (isDisabled: boolean) => void): void; registerOnDisabledChange(fn: (isDisabled: boolean) => void): void;
reset(formState?: any, {onlySelf}?: { reset(formState?: any, {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
setValue(value: any, {onlySelf, emitEvent, emitModelToViewChange, emitViewToModelChange}?: { setValue(value: any, {onlySelf, emitEvent, emitModelToViewChange, emitViewToModelChange}?: {
onlySelf?: boolean; onlySelf?: boolean;
@ -267,19 +271,22 @@ export declare class FormGroup extends AbstractControl {
getRawValue(): Object; getRawValue(): Object;
patchValue(value: { patchValue(value: {
[key: string]: any; [key: string]: any;
}, {onlySelf}?: { }, {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
registerControl(name: string, control: AbstractControl): AbstractControl; registerControl(name: string, control: AbstractControl): AbstractControl;
removeControl(name: string): void; removeControl(name: string): void;
reset(value?: any, {onlySelf}?: { reset(value?: any, {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
setControl(name: string, control: AbstractControl): void; setControl(name: string, control: AbstractControl): void;
setValue(value: { setValue(value: {
[key: string]: any; [key: string]: any;
}, {onlySelf}?: { }, {onlySelf, emitEvent}?: {
onlySelf?: boolean; onlySelf?: boolean;
emitEvent?: boolean;
}): void; }): void;
} }