Свойство 'controls' не существует в типе 'AbstractControl' Angular 4

Я пытаюсь вставить реактивную форму в Angular 4. Он работает нормально, но когда я пытаюсь построить AOT, он бросает ошибку

'controls' не существует в типе 'AbstractControl'

Я googled и пробовал несколько вещей, но не повезло. Может ли кто-нибудь сказать мне, как исправить эту проблему?

<div [formGroup]="myForm">
    <div formArrayName="addresses">
        <div *ngFor="let address of myForm.get('addresses').controls; let i=index" 
                    class="panel panel-default">
            <span *ngIf="myForm.get('addresses').length > 1"
                    (click)="removeAddress(i)">Remove</span>
            <div [formGroupName]="i">
                <mat-form-field>
                    <input matInput formControlName="city" placeholder="city" value="">
                </mat-form-field>
            </div>

        </div>
    </div>
    <a (click)="addAddress()" style="cursor: default"> Add +</a>
</div>

машинописный код ниже

constructor(private _fb: FormBuilder) {     
}

ngOnInit() {
    this.myForm = this._fb.group({
        addresses: this._fb.array([
            this.initAddress(),
        ])
    });
}
initAddress() {
    return this._fb.group({
        city: ['']
    });
}
addAddress() {
    const control = <FormArray>this.myForm.get('addresses');
    control.push(this.initAddress());
}
removeAddress(i: number) {
    const control = <FormArray>this.myForm.get('addresses');
    control.removeAt(i);
}

Ответ 1

Основываясь на комментариях @Günter Zöchbauer, сначала я изменил

myForm.controls['addresses'] в myForm.get('addresses') в html и машинописном тексте

а затем на основе комментария @yuruzi

изменено myForm.get('addresses').controls myForm.get('addresses')['controls']

Теперь он работает отлично. Спасибо @gunter & yuruzi

Ответ 2

Вы можете исправить это легко, хотя. Передайте логику "получить элементы управления" в метод кода вашего компонента (файл .ts):

'getControls() {
  return (this.recipeForm.get('controlName') as FormArray).controls;
}'

В шаблоне вы можете использовать:

*ngFor="let ingredientCtrl of getControls(); let i = index"

Эта настройка требуется из-за того, как TS работает и Angular анализирует ваши шаблоны (он не понимает TS там).

Ответ 3

В качестве обновления решения @sunny kashyap я написал бы это так:

getControls() {
  return (this.recipeForm.get('controlName') as FormArray).controls;
}

Ответ 4

чтобы получить длину FormArray, используйте просто length:

<span *ngIf="myForm.controls['addresses'].length > 1" (click)="removeAddress(i)">Remove</span>

Надеюсь, поможет

Ответ 5

Измените myForm.get('addresses').controls myForm.get('addresses').value на myForm.get('addresses').value также исправит проблему.

Ответ 6

для ошибок проверки используйте...

<span *ngIf="f.YOUR_FORM_KEY.controls.YOUR_FORM_KEY.errors?.YOUR_FORM_VALIDATION">YOUR_FORM_KEY is YOUR_FORM_VALIDATION</span>

например.

<span *ngIf="f.name.controls.name.errors?.required">Name is required</span>

TS файл

get f(): any {
    return this.userForm.controls;
}