fix(forms): fully support rebinding form group directive (#11051)
This commit is contained in:
@@ -17,7 +17,7 @@ import {ControlContainer} from '../control_container';
|
||||
import {Form} from '../form_interface';
|
||||
import {NgControl} from '../ng_control';
|
||||
import {ReactiveErrors} from '../reactive_errors';
|
||||
import {composeAsyncValidators, composeValidators, setUpControl, setUpFormContainer} from '../shared';
|
||||
import {cleanUpControl, composeAsyncValidators, composeValidators, setUpControl, setUpFormContainer} from '../shared';
|
||||
|
||||
import {FormArrayName, FormGroupName} from './form_group_name';
|
||||
|
||||
@@ -124,11 +124,9 @@ export class FormGroupDirective extends ControlContainer implements Form,
|
||||
|
||||
var async = composeAsyncValidators(this._asyncValidators);
|
||||
this.form.asyncValidator = Validators.composeAsync([this.form.asyncValidator, async]);
|
||||
|
||||
this.form.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||
this._updateDomValue(changes);
|
||||
}
|
||||
|
||||
this._updateDomValue();
|
||||
}
|
||||
|
||||
get submitted(): boolean { return this._submitted; }
|
||||
@@ -189,10 +187,15 @@ export class FormGroupDirective extends ControlContainer implements Form,
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_updateDomValue() {
|
||||
_updateDomValue(changes: SimpleChanges) {
|
||||
const oldForm = changes['form'].previousValue;
|
||||
this.directives.forEach(dir => {
|
||||
var ctrl: any = this.form.get(dir.path);
|
||||
dir.valueAccessor.writeValue(ctrl.value);
|
||||
const newCtrl: any = this.form.get(dir.path);
|
||||
const oldCtrl = oldForm.get(dir.path);
|
||||
if (oldCtrl !== newCtrl) {
|
||||
cleanUpControl(oldCtrl, dir);
|
||||
if (newCtrl) setUpControl(newCtrl, dir);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ export function setUpControl(control: FormControl, dir: NgControl): void {
|
||||
dir.valueAccessor.registerOnTouched(() => control.markAsTouched());
|
||||
}
|
||||
|
||||
export function cleanUpControl(control: FormControl, dir: NgControl) {
|
||||
dir.valueAccessor.registerOnChange(() => _noControlError(dir));
|
||||
dir.valueAccessor.registerOnTouched(() => _noControlError(dir));
|
||||
if (control) control._clearChangeFns();
|
||||
}
|
||||
|
||||
export function setUpFormContainer(
|
||||
control: FormGroup | FormArray, dir: AbstractFormGroupDirective | FormArrayName) {
|
||||
if (isBlank(control)) _throwError(dir, 'Cannot find control with');
|
||||
@@ -74,6 +80,10 @@ export function setUpFormContainer(
|
||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||
}
|
||||
|
||||
function _noControlError(dir: NgControl) {
|
||||
return _throwError(dir, 'There is no FormControl instance attached to form control element with');
|
||||
}
|
||||
|
||||
function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||
let messageEnd: string;
|
||||
if (dir.path.length > 1) {
|
||||
|
||||
@@ -519,6 +519,14 @@ export class FormControl extends AbstractControl {
|
||||
*/
|
||||
registerOnChange(fn: Function): void { this._onChange.push(fn); }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_clearChangeFns(): void {
|
||||
this._onChange = [];
|
||||
this._onDisabledChange = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for disabled events.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user