parent
a55d796c4b
commit
d6d4568830
|
@ -16,11 +16,10 @@ import {NgModel} from './directives/ng_model';
|
||||||
import {NgModelGroup} from './directives/ng_model_group';
|
import {NgModelGroup} from './directives/ng_model_group';
|
||||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
import {FormArrayName} from './directives/reactive_directives/form_array_name';
|
|
||||||
import {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
import {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
||||||
import {FormControlName} from './directives/reactive_directives/form_control_name';
|
import {FormControlName} from './directives/reactive_directives/form_control_name';
|
||||||
import {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
import {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
||||||
import {FormGroupName} from './directives/reactive_directives/form_group_name';
|
import {FormArrayName, FormGroupName} from './directives/reactive_directives/form_group_name';
|
||||||
import {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
import {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||||
import {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
import {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||||
import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
import {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||||
|
@ -35,11 +34,10 @@ export {NgModel} from './directives/ng_model';
|
||||||
export {NgModelGroup} from './directives/ng_model_group';
|
export {NgModelGroup} from './directives/ng_model_group';
|
||||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
export {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
export {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
export {FormArrayName} from './directives/reactive_directives/form_array_name';
|
|
||||||
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
||||||
export {FormControlName} from './directives/reactive_directives/form_control_name';
|
export {FormControlName} from './directives/reactive_directives/form_control_name';
|
||||||
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
||||||
export {FormGroupName} from './directives/reactive_directives/form_group_name';
|
export {FormArrayName, FormGroupName} from './directives/reactive_directives/form_group_name';
|
||||||
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||||
export {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
export {NgSelectMultipleOption, SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||||
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
export {MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator} from './directives/validators';
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Directive, Host, Inject, Input, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
|
||||||
|
|
||||||
import {BaseException} from '../../facade/exceptions';
|
|
||||||
import {FormArray} from '../../model';
|
|
||||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
|
||||||
import {ControlContainer} from '../control_container';
|
|
||||||
import {ReactiveErrors} from '../reactive_errors';
|
|
||||||
import {composeAsyncValidators, composeValidators, controlPath} from '../shared';
|
|
||||||
import {AsyncValidatorFn, ValidatorFn} from '../validators';
|
|
||||||
|
|
||||||
import {FormGroupDirective} from './form_group_directive';
|
|
||||||
import {FormGroupName} from './form_group_name';
|
|
||||||
|
|
||||||
export const formArrayNameProvider: any = {
|
|
||||||
provide: ControlContainer,
|
|
||||||
useExisting: forwardRef(() => FormArrayName)
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Syncs an existing form array to a DOM element.
|
|
||||||
*
|
|
||||||
* This directive can only be used as a child of {@link FormGroupDirective}.
|
|
||||||
*
|
|
||||||
* ```typescript
|
|
||||||
* @Component({
|
|
||||||
* selector: 'my-app',
|
|
||||||
* template: `
|
|
||||||
* <div>
|
|
||||||
* <h2>Angular FormArray Example</h2>
|
|
||||||
* <form [formGroup]="myForm">
|
|
||||||
* <div formArrayName="cities">
|
|
||||||
* <div *ngFor="let city of cityArray.controls; let i=index">
|
|
||||||
* <input [formControlName]="i">
|
|
||||||
* </div>
|
|
||||||
* </div>
|
|
||||||
* </form>
|
|
||||||
* {{ myForm.value | json }} // {cities: ['SF', 'NY']}
|
|
||||||
* </div>
|
|
||||||
* `
|
|
||||||
* })
|
|
||||||
* export class App {
|
|
||||||
* cityArray = new FormArray([
|
|
||||||
* new FormControl('SF'),
|
|
||||||
* new FormControl('NY')
|
|
||||||
* ]);
|
|
||||||
* myForm = new FormGroup({
|
|
||||||
* cities: this.cityArray
|
|
||||||
* });
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
@Directive({selector: '[formArrayName]', providers: [formArrayNameProvider]})
|
|
||||||
export class FormArrayName extends ControlContainer implements OnInit, OnDestroy {
|
|
||||||
/** @internal */
|
|
||||||
_parent: ControlContainer;
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
_validators: any[];
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
_asyncValidators: any[];
|
|
||||||
|
|
||||||
@Input('formArrayName') name: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@Optional() @Host() @SkipSelf() parent: ControlContainer,
|
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
|
||||||
super();
|
|
||||||
this._parent = parent;
|
|
||||||
this._validators = validators;
|
|
||||||
this._asyncValidators = asyncValidators;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this._checkParentType();
|
|
||||||
this.formDirective.addFormArray(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void { this.formDirective.removeFormArray(this); }
|
|
||||||
|
|
||||||
get control(): FormArray { return this.formDirective.getFormArray(this); }
|
|
||||||
|
|
||||||
get formDirective(): FormGroupDirective { return <FormGroupDirective>this._parent.formDirective; }
|
|
||||||
|
|
||||||
get path(): string[] { return controlPath(this.name, this._parent); }
|
|
||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
|
||||||
|
|
||||||
private _checkParentType(): void {
|
|
||||||
if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective)) {
|
|
||||||
ReactiveErrors.arrayParentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@
|
||||||
import {Directive, Host, Inject, Input, OnChanges, OnDestroy, Optional, Output, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
|
import {Directive, Host, Inject, Input, OnChanges, OnDestroy, Optional, Output, Self, SimpleChanges, SkipSelf, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
import {EventEmitter, ObservableWrapper} from '../../facade/async';
|
||||||
import {BaseException} from '../../facade/exceptions';
|
|
||||||
import {FormControl} from '../../model';
|
import {FormControl} from '../../model';
|
||||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
||||||
import {AbstractFormGroupDirective} from '../abstract_form_group_directive';
|
import {AbstractFormGroupDirective} from '../abstract_form_group_directive';
|
||||||
|
@ -20,10 +19,8 @@ import {ReactiveErrors} from '../reactive_errors';
|
||||||
import {composeAsyncValidators, composeValidators, controlPath, isPropertyUpdated, selectValueAccessor} from '../shared';
|
import {composeAsyncValidators, composeValidators, controlPath, isPropertyUpdated, selectValueAccessor} from '../shared';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from '../validators';
|
import {AsyncValidatorFn, ValidatorFn} from '../validators';
|
||||||
|
|
||||||
import {FormArrayName} from './form_array_name';
|
|
||||||
import {FormGroupDirective} from './form_group_directive';
|
import {FormGroupDirective} from './form_group_directive';
|
||||||
import {FormGroupName} from './form_group_name';
|
import {FormArrayName, FormGroupName} from './form_group_name';
|
||||||
|
|
||||||
|
|
||||||
export const controlNameBinding: any = {
|
export const controlNameBinding: any = {
|
||||||
provide: NgControl,
|
provide: NgControl,
|
||||||
|
|
|
@ -20,8 +20,7 @@ import {NgControl} from '../ng_control';
|
||||||
import {ReactiveErrors} from '../reactive_errors';
|
import {ReactiveErrors} from '../reactive_errors';
|
||||||
import {composeAsyncValidators, composeValidators, setUpControl, setUpFormContainer} from '../shared';
|
import {composeAsyncValidators, composeValidators, setUpControl, setUpFormContainer} from '../shared';
|
||||||
|
|
||||||
import {FormArrayName} from './form_array_name';
|
import {FormArrayName, FormGroupName} from './form_group_name';
|
||||||
import {FormGroupName} from './form_group_name';
|
|
||||||
|
|
||||||
export const formDirectiveProvider: any = {
|
export const formDirectiveProvider: any = {
|
||||||
provide: ControlContainer,
|
provide: ControlContainer,
|
||||||
|
|
|
@ -8,11 +8,13 @@
|
||||||
|
|
||||||
import {Directive, Host, Inject, Input, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
import {Directive, Host, Inject, Input, OnDestroy, OnInit, Optional, Self, SkipSelf, forwardRef} from '@angular/core';
|
||||||
|
|
||||||
import {BaseException} from '../../facade/exceptions';
|
import {FormArray} from '../../model';
|
||||||
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
import {NG_ASYNC_VALIDATORS, NG_VALIDATORS} from '../../validators';
|
||||||
import {AbstractFormGroupDirective} from '../abstract_form_group_directive';
|
import {AbstractFormGroupDirective} from '../abstract_form_group_directive';
|
||||||
import {ControlContainer} from '../control_container';
|
import {ControlContainer} from '../control_container';
|
||||||
import {ReactiveErrors} from '../reactive_errors';
|
import {ReactiveErrors} from '../reactive_errors';
|
||||||
|
import {composeAsyncValidators, composeValidators, controlPath} from '../shared';
|
||||||
|
import {AsyncValidatorFn, ValidatorFn} from '../validators';
|
||||||
|
|
||||||
import {FormGroupDirective} from './form_group_directive';
|
import {FormGroupDirective} from './form_group_directive';
|
||||||
|
|
||||||
|
@ -85,8 +87,100 @@ export class FormGroupName extends AbstractFormGroupDirective implements OnInit,
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_checkParentType(): void {
|
_checkParentType(): void {
|
||||||
if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective)) {
|
if (_hasInvalidParent(this._parent)) {
|
||||||
ReactiveErrors.groupParentException();
|
ReactiveErrors.groupParentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formArrayNameProvider: any = {
|
||||||
|
provide: ControlContainer,
|
||||||
|
useExisting: forwardRef(() => FormArrayName)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncs an existing form array to a DOM element.
|
||||||
|
*
|
||||||
|
* This directive can only be used as a child of {@link FormGroupDirective}.
|
||||||
|
*
|
||||||
|
* ```typescript
|
||||||
|
* @Component({
|
||||||
|
* selector: 'my-app',
|
||||||
|
* template: `
|
||||||
|
* <div>
|
||||||
|
* <h2>Angular FormArray Example</h2>
|
||||||
|
* <form [formGroup]="myForm">
|
||||||
|
* <div formArrayName="cities">
|
||||||
|
* <div *ngFor="let city of cityArray.controls; let i=index">
|
||||||
|
* <input [formControlName]="i">
|
||||||
|
* </div>
|
||||||
|
* </div>
|
||||||
|
* </form>
|
||||||
|
* {{ myForm.value | json }} // {cities: ['SF', 'NY']}
|
||||||
|
* </div>
|
||||||
|
* `
|
||||||
|
* })
|
||||||
|
* export class App {
|
||||||
|
* cityArray = new FormArray([
|
||||||
|
* new FormControl('SF'),
|
||||||
|
* new FormControl('NY')
|
||||||
|
* ]);
|
||||||
|
* myForm = new FormGroup({
|
||||||
|
* cities: this.cityArray
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @experimental
|
||||||
|
*/
|
||||||
|
@Directive({selector: '[formArrayName]', providers: [formArrayNameProvider]})
|
||||||
|
export class FormArrayName extends ControlContainer implements OnInit, OnDestroy {
|
||||||
|
/** @internal */
|
||||||
|
_parent: ControlContainer;
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
_validators: any[];
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
_asyncValidators: any[];
|
||||||
|
|
||||||
|
@Input('formArrayName') name: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Optional() @Host() @SkipSelf() parent: ControlContainer,
|
||||||
|
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||||
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||||
|
super();
|
||||||
|
this._parent = parent;
|
||||||
|
this._validators = validators;
|
||||||
|
this._asyncValidators = asyncValidators;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this._checkParentType();
|
||||||
|
this.formDirective.addFormArray(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void { this.formDirective.removeFormArray(this); }
|
||||||
|
|
||||||
|
get control(): FormArray { return this.formDirective.getFormArray(this); }
|
||||||
|
|
||||||
|
get formDirective(): FormGroupDirective { return <FormGroupDirective>this._parent.formDirective; }
|
||||||
|
|
||||||
|
get path(): string[] { return controlPath(this.name, this._parent); }
|
||||||
|
|
||||||
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
|
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||||
|
|
||||||
|
private _checkParentType(): void {
|
||||||
|
if (_hasInvalidParent(this._parent)) {
|
||||||
|
ReactiveErrors.arrayParentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _hasInvalidParent(parent: ControlContainer): boolean {
|
||||||
|
return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) &&
|
||||||
|
!(parent instanceof FormArrayName);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {BaseException} from '../facade/exceptions';
|
import {BaseException} from '../facade/exceptions';
|
||||||
|
|
||||||
import {FormErrorExamples as Examples} from './error_examples';
|
import {FormErrorExamples as Examples} from './error_examples';
|
||||||
|
|
||||||
export class ReactiveErrors {
|
export class ReactiveErrors {
|
||||||
|
@ -60,4 +61,4 @@ export class ReactiveErrors {
|
||||||
|
|
||||||
${Examples.formArrayName}`);
|
${Examples.formArrayName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {NgControl} from './ng_control';
|
||||||
import {normalizeAsyncValidator, normalizeValidator} from './normalize_validator';
|
import {normalizeAsyncValidator, normalizeValidator} from './normalize_validator';
|
||||||
import {NumberValueAccessor} from './number_value_accessor';
|
import {NumberValueAccessor} from './number_value_accessor';
|
||||||
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './radio_control_value_accessor';
|
||||||
import {FormArrayName} from './reactive_directives/form_array_name';
|
import {FormArrayName} from './reactive_directives/form_group_name';
|
||||||
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
import {SelectControlValueAccessor} from './select_control_value_accessor';
|
||||||
import {SelectMultipleControlValueAccessor} from './select_multiple_control_value_accessor';
|
import {SelectMultipleControlValueAccessor} from './select_multiple_control_value_accessor';
|
||||||
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
import {AsyncValidatorFn, ValidatorFn} from './validators';
|
||||||
|
|
|
@ -33,10 +33,10 @@ export {NgControlStatus} from './directives/ng_control_status';
|
||||||
export {NgForm} from './directives/ng_form';
|
export {NgForm} from './directives/ng_form';
|
||||||
export {NgModel} from './directives/ng_model';
|
export {NgModel} from './directives/ng_model';
|
||||||
export {NgModelGroup} from './directives/ng_model_group';
|
export {NgModelGroup} from './directives/ng_model_group';
|
||||||
export {FormArrayName} from './directives/reactive_directives/form_array_name';
|
|
||||||
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
export {FormControlDirective} from './directives/reactive_directives/form_control_directive';
|
||||||
export {FormControlName} from './directives/reactive_directives/form_control_name';
|
export {FormControlName} from './directives/reactive_directives/form_control_name';
|
||||||
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
export {FormGroupDirective} from './directives/reactive_directives/form_group_directive';
|
||||||
|
export {FormArrayName} from './directives/reactive_directives/form_group_name';
|
||||||
export {FormGroupName} from './directives/reactive_directives/form_group_name';
|
export {FormGroupName} from './directives/reactive_directives/form_group_name';
|
||||||
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
export {NgSelectOption, SelectControlValueAccessor} from './directives/select_control_value_accessor';
|
||||||
export {SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
export {SelectMultipleControlValueAccessor} from './directives/select_multiple_control_value_accessor';
|
||||||
|
|
|
@ -350,11 +350,13 @@ export function main() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should support form arrays',
|
it('should support form arrays',
|
||||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
inject(
|
||||||
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
const form = new FormGroup({cities: cityArray});
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
|
||||||
|
const form = new FormGroup({cities: cityArray});
|
||||||
|
|
||||||
const t = `<div [formGroup]="form">
|
const t = `<div [formGroup]="form">
|
||||||
<div formArrayName="cities">
|
<div formArrayName="cities">
|
||||||
<div *ngFor="let city of cityArray.controls; let i=index">
|
<div *ngFor="let city of cityArray.controls; let i=index">
|
||||||
<input [formControlName]="i">
|
<input [formControlName]="i">
|
||||||
|
@ -362,27 +364,71 @@ export function main() {
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
|
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
|
||||||
fixture.debugElement.componentInstance.form = form;
|
fixture.debugElement.componentInstance.form = form;
|
||||||
fixture.debugElement.componentInstance.cityArray = cityArray;
|
fixture.debugElement.componentInstance.cityArray = cityArray;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick();
|
|
||||||
|
|
||||||
const inputs = fixture.debugElement.queryAll(By.css('input'));
|
const inputs = fixture.debugElement.queryAll(By.css('input'));
|
||||||
expect(inputs[0].nativeElement.value).toEqual('SF');
|
expect(inputs[0].nativeElement.value).toEqual('SF');
|
||||||
expect(inputs[1].nativeElement.value).toEqual('NY');
|
expect(inputs[1].nativeElement.value).toEqual('NY');
|
||||||
expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY']});
|
expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY']});
|
||||||
|
|
||||||
inputs[0].nativeElement.value = 'LA';
|
inputs[0].nativeElement.value = 'LA';
|
||||||
dispatchEvent(inputs[0].nativeElement, 'input');
|
dispatchEvent(inputs[0].nativeElement, 'input');
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick();
|
|
||||||
|
|
||||||
expect(fixture.componentInstance.form.value).toEqual({cities: ['LA', 'NY']});
|
expect(fixture.componentInstance.form.value).toEqual({cities: ['LA', 'NY']});
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
});
|
it('should support form groups nested in form arrays',
|
||||||
})));
|
inject(
|
||||||
|
[TestComponentBuilder, AsyncTestCompleter],
|
||||||
|
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
|
||||||
|
const cityArray = new FormArray([
|
||||||
|
new FormGroup({town: new FormControl('SF'), state: new FormControl('CA')}),
|
||||||
|
new FormGroup({town: new FormControl('NY'), state: new FormControl('NY')})
|
||||||
|
]);
|
||||||
|
const form = new FormGroup({cities: cityArray});
|
||||||
|
|
||||||
|
const t = `<div [formGroup]="form">
|
||||||
|
<div formArrayName="cities">
|
||||||
|
<div *ngFor="let city of cityArray.controls; let i=index" [formGroupName]="i">
|
||||||
|
<input formControlName="town">
|
||||||
|
<input formControlName="state">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
|
||||||
|
fixture.debugElement.componentInstance.form = form;
|
||||||
|
fixture.debugElement.componentInstance.cityArray = cityArray;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const inputs = fixture.debugElement.queryAll(By.css('input'));
|
||||||
|
expect(inputs[0].nativeElement.value).toEqual('SF');
|
||||||
|
expect(inputs[1].nativeElement.value).toEqual('CA');
|
||||||
|
expect(inputs[2].nativeElement.value).toEqual('NY');
|
||||||
|
expect(inputs[3].nativeElement.value).toEqual('NY');
|
||||||
|
expect(fixture.componentInstance.form.value).toEqual({
|
||||||
|
cities: [{town: 'SF', state: 'CA'}, {town: 'NY', state: 'NY'}]
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs[0].nativeElement.value = 'LA';
|
||||||
|
dispatchEvent(inputs[0].nativeElement, 'input');
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.componentInstance.form.value).toEqual({
|
||||||
|
cities: [{town: 'LA', state: 'CA'}, {town: 'NY', state: 'NY'}]
|
||||||
|
});
|
||||||
|
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should support pushing new controls to form arrays',
|
it('should support pushing new controls to form arrays',
|
||||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
|
|
Loading…
Reference in New Issue