diff --git a/packages/forms/src/directives/ng_control.ts b/packages/forms/src/directives/ng_control.ts index 0314773902..de09f7ff83 100644 --- a/packages/forms/src/directives/ng_control.ts +++ b/packages/forms/src/directives/ng_control.ts @@ -36,7 +36,7 @@ export abstract class NgControl extends AbstractControlDirective { * @description * The name for the control */ - name: string|null = null; + name: string|number|null = null; /** * @description diff --git a/packages/forms/src/directives/reactive_directives/form_control_name.ts b/packages/forms/src/directives/reactive_directives/form_control_name.ts index 11992e5842..784ea62a30 100644 --- a/packages/forms/src/directives/reactive_directives/form_control_name.ts +++ b/packages/forms/src/directives/reactive_directives/form_control_name.ts @@ -145,9 +145,13 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy { * @description * Tracks the name of the `FormControl` bound to the directive. The name corresponds * to a key in the parent `FormGroup` or `FormArray`. + * Accepts a name as a string or a number. + * The name in the form of a string is useful for individual forms, + * while the numerical form allows for form controls to be bound + * to indices when iterating over controls in a `FormArray`. */ // TODO(issue/24571): remove '!'. - @Input('formControlName') name !: string; + @Input('formControlName') name !: string | number | null; /** * @description @@ -238,7 +242,9 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy { * Returns an array that represents the path from the top-level form to this control. * Each index is the string name of the control on that level. */ - get path(): string[] { return controlPath(this.name, this._parent !); } + get path(): string[] { + return controlPath(this.name == null ? this.name : this.name.toString(), this._parent !); + } /** * @description diff --git a/packages/forms/src/directives/shared.ts b/packages/forms/src/directives/shared.ts index f40274a653..17347db421 100644 --- a/packages/forms/src/directives/shared.ts +++ b/packages/forms/src/directives/shared.ts @@ -28,8 +28,8 @@ import {SelectMultipleControlValueAccessor} from './select_multiple_control_valu import {AsyncValidator, AsyncValidatorFn, Validator, ValidatorFn} from './validators'; -export function controlPath(name: string, parent: ControlContainer): string[] { - return [...parent.path !, name]; +export function controlPath(name: string | null, parent: ControlContainer): string[] { + return [...parent.path !, name !]; } export function setUpControl(control: FormControl, dir: NgControl): void { diff --git a/tools/public_api_guard/forms/forms.d.ts b/tools/public_api_guard/forms/forms.d.ts index 577885628b..2b791597ae 100644 --- a/tools/public_api_guard/forms/forms.d.ts +++ b/tools/public_api_guard/forms/forms.d.ts @@ -255,7 +255,7 @@ export declare class FormControlName extends NgControl implements OnChanges, OnD readonly formDirective: any; isDisabled: boolean; /** @deprecated */ model: any; - name: string; + name: string | number | null; readonly path: string[]; /** @deprecated */ update: EventEmitter; readonly validator: ValidatorFn | null; @@ -353,7 +353,7 @@ export declare const NG_VALUE_ACCESSOR: InjectionToken; export declare abstract class NgControl extends AbstractControlDirective { readonly asyncValidator: AsyncValidatorFn | null; - name: string | null; + name: string | number | null; readonly validator: ValidatorFn | null; valueAccessor: ControlValueAccessor | null; abstract viewToModelUpdate(newValue: any): void;