fix(forms): support rebinding nested controls (#11210)
This commit is contained in:
@ -552,6 +552,7 @@ export function main() {
|
||||
parent.form = new FormGroup({'name': formModel});
|
||||
controlNameDir = new FormControlName(parent, [], [], [defaultAccessor]);
|
||||
controlNameDir.name = 'name';
|
||||
controlNameDir._control = formModel;
|
||||
});
|
||||
|
||||
it('should reexport control properties', () => {
|
||||
|
@ -806,6 +806,49 @@ export function main() {
|
||||
|
||||
});
|
||||
|
||||
describe('setControl()', () => {
|
||||
let c: FormControl;
|
||||
let a: FormArray;
|
||||
|
||||
beforeEach(() => {
|
||||
c = new FormControl('one');
|
||||
a = new FormArray([c]);
|
||||
});
|
||||
|
||||
it('should replace existing control with new control', () => {
|
||||
const c2 = new FormControl('new!', Validators.minLength(10));
|
||||
a.setControl(0, c2);
|
||||
|
||||
expect(a.controls[0]).toEqual(c2);
|
||||
expect(a.value).toEqual(['new!']);
|
||||
expect(a.valid).toBe(false);
|
||||
});
|
||||
|
||||
it('should add control if control did not exist before', () => {
|
||||
const c2 = new FormControl('new!', Validators.minLength(10));
|
||||
a.setControl(1, c2);
|
||||
|
||||
expect(a.controls[1]).toEqual(c2);
|
||||
expect(a.value).toEqual(['one', 'new!']);
|
||||
expect(a.valid).toBe(false);
|
||||
});
|
||||
|
||||
it('should remove control if new control is null', () => {
|
||||
a.setControl(0, null);
|
||||
expect(a.controls[0]).not.toBeDefined();
|
||||
expect(a.value).toEqual([]);
|
||||
});
|
||||
|
||||
it('should only emit value change event once', () => {
|
||||
const logger: string[] = [];
|
||||
const c2 = new FormControl('new!');
|
||||
a.valueChanges.subscribe(() => logger.push('change!'));
|
||||
a.setControl(0, c2);
|
||||
expect(logger).toEqual(['change!']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -842,6 +842,49 @@ export function main() {
|
||||
|
||||
});
|
||||
|
||||
describe('setControl()', () => {
|
||||
let c: FormControl;
|
||||
let g: FormGroup;
|
||||
|
||||
beforeEach(() => {
|
||||
c = new FormControl('one');
|
||||
g = new FormGroup({one: c});
|
||||
});
|
||||
|
||||
it('should replace existing control with new control', () => {
|
||||
const c2 = new FormControl('new!', Validators.minLength(10));
|
||||
g.setControl('one', c2);
|
||||
|
||||
expect(g.controls['one']).toEqual(c2);
|
||||
expect(g.value).toEqual({one: 'new!'});
|
||||
expect(g.valid).toBe(false);
|
||||
});
|
||||
|
||||
it('should add control if control did not exist before', () => {
|
||||
const c2 = new FormControl('new!', Validators.minLength(10));
|
||||
g.setControl('two', c2);
|
||||
|
||||
expect(g.controls['two']).toEqual(c2);
|
||||
expect(g.value).toEqual({one: 'one', two: 'new!'});
|
||||
expect(g.valid).toBe(false);
|
||||
});
|
||||
|
||||
it('should remove control if new control is null', () => {
|
||||
g.setControl('one', null);
|
||||
expect(g.controls['one']).not.toBeDefined();
|
||||
expect(g.value).toEqual({});
|
||||
});
|
||||
|
||||
it('should only emit value change event once', () => {
|
||||
const logger: string[] = [];
|
||||
const c2 = new FormControl('new!');
|
||||
g.valueChanges.subscribe(() => logger.push('change!'));
|
||||
g.setControl('one', c2);
|
||||
expect(logger).toEqual(['change!']);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -256,6 +256,91 @@ export function main() {
|
||||
expect(inputs[2]).not.toBeDefined();
|
||||
});
|
||||
|
||||
describe('nested control rebinding', () => {
|
||||
|
||||
it('should attach dir to control when leaf control changes', () => {
|
||||
const form = new FormGroup({'login': new FormControl('oldValue')});
|
||||
const fixture = TestBed.createComponent(FormGroupComp);
|
||||
fixture.debugElement.componentInstance.form = form;
|
||||
fixture.detectChanges();
|
||||
|
||||
form.removeControl('login');
|
||||
form.addControl('login', new FormControl('newValue'));
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.query(By.css('input'));
|
||||
expect(input.nativeElement.value).toEqual('newValue');
|
||||
|
||||
input.nativeElement.value = 'user input';
|
||||
dispatchEvent(input.nativeElement, 'input');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(form.value).toEqual({login: 'user input'});
|
||||
|
||||
form.setValue({login: 'Carson'});
|
||||
fixture.detectChanges();
|
||||
expect(input.nativeElement.value).toEqual('Carson');
|
||||
});
|
||||
|
||||
it('should attach dirs to all child controls when group control changes', () => {
|
||||
const fixture = TestBed.createComponent(NestedFormGroupComp);
|
||||
const form = new FormGroup({
|
||||
signin: new FormGroup(
|
||||
{login: new FormControl('oldLogin'), password: new FormControl('oldPassword')})
|
||||
});
|
||||
fixture.debugElement.componentInstance.form = form;
|
||||
fixture.detectChanges();
|
||||
|
||||
form.removeControl('signin');
|
||||
form.addControl(
|
||||
'signin',
|
||||
new FormGroup(
|
||||
{login: new FormControl('newLogin'), password: new FormControl('newPassword')}));
|
||||
fixture.detectChanges();
|
||||
|
||||
const inputs = fixture.debugElement.queryAll(By.css('input'));
|
||||
expect(inputs[0].nativeElement.value).toEqual('newLogin');
|
||||
expect(inputs[1].nativeElement.value).toEqual('newPassword');
|
||||
|
||||
inputs[0].nativeElement.value = 'user input';
|
||||
dispatchEvent(inputs[0].nativeElement, 'input');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(form.value).toEqual({signin: {login: 'user input', password: 'newPassword'}});
|
||||
|
||||
form.setValue({signin: {login: 'Carson', password: 'Drew'}});
|
||||
fixture.detectChanges();
|
||||
expect(inputs[0].nativeElement.value).toEqual('Carson');
|
||||
expect(inputs[1].nativeElement.value).toEqual('Drew');
|
||||
});
|
||||
|
||||
it('should attach dirs to all present child controls when array control changes', () => {
|
||||
const fixture = TestBed.createComponent(FormArrayComp);
|
||||
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
|
||||
const form = new FormGroup({cities: cityArray});
|
||||
fixture.debugElement.componentInstance.form = form;
|
||||
fixture.debugElement.componentInstance.cityArray = cityArray;
|
||||
fixture.detectChanges();
|
||||
|
||||
form.removeControl('cities');
|
||||
form.addControl('cities', new FormArray([new FormControl('LA')]));
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.query(By.css('input'));
|
||||
expect(input.nativeElement.value).toEqual('LA');
|
||||
|
||||
input.nativeElement.value = 'MTV';
|
||||
dispatchEvent(input.nativeElement, 'input');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(form.value).toEqual({cities: ['MTV']});
|
||||
|
||||
form.setValue({cities: ['LA']});
|
||||
fixture.detectChanges();
|
||||
expect(input.nativeElement.value).toEqual('LA');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user