fix(forms): fully support rebinding form group directive (#11051)

This commit is contained in:
Kara
2016-08-25 14:37:57 -07:00
committed by Victor Berchet
parent d7c82f5c0f
commit 515ff61fcb
4 changed files with 194 additions and 10 deletions
@@ -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) {
+8
View File
@@ -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.
*/