错误 属性 'controls' 在类型 'AbstractControl' 上不存在。在编译生产时

Error Property 'controls' does not exist on type 'AbstractControl'. while compiling for production

您好,我在编译项目时遇到错误。我正在使用 angular 5 和打字稿。

我正在提供一个 npm 运行 build 和项目根文件夹,以下是我收到的错误。

bash-4.2$ npm run build
> primecast@5.0.1 build /tmp/tester001/mep-private/ui
> ng build --prod

 10% building modules 3/4 modules 1 active ...ter001/mep-private/ui/src/styles.scssNode#moveTo was deprecated. Use Container#append.
Date: 2019-12-20T11:17:00.575Z                                                     
Hash: 175df3f370fd7976d3c4
Time: 16261ms
chunk {0} styles.bb4ae0c2b0dd75fdc7ee.bundle.css (styles) 159 kB [initial] [rendered]
chunk {1} polyfills.3bc34265385d52184eab.bundle.js (polyfills) 86 bytes [initial] [rendered]
chunk {2} main.e402deade8b026b7d50e.bundle.js (main) 84 bytes [initial] [rendered]
chunk {3} inline.9d07561b59257af76b95.bundle.js (inline) 1.45 kB [entry] [rendered]

ERROR in src/app/accounts/account-service-provider-clients/account-service-provider-clients.component.html(17,28): : Property 'controls' does not exist on type 'AbstractControl'.

以下是account-service-provider的内容-clients.component.html

<form novalidate [formGroup]="formGroup">
<div formArrayName="aliases">
  <div [formGroupName]="i" *ngFor="let item of formGroup.get('aliases').controls; let i = index">
    <div class="row">
        <div class="col-2">
          <input type="hidden" formControlName="id" >
          <pc-form-field [errorMessages]="['required','maxlength']">
            <input type="text" formControlName="name" [placeholder]="'PLACEHOLDERS.SERVICE_PROVIDER_CLIENT_NAME' | translate" name="client-name">
          </pc-form-field>
        </div>
        <div class="col-2">
          <pc-form-field [errorMessages]="['maxlength']">
            <input type="text" formControlName="companyNumber" [placeholder]="'PLACEHOLDERS.SERVICE_PROVIDER_CLIENT_COMPANY_NUMBER' | translate" name="company-number">
          </pc-form-field>
        </div>
        <div class="col-2">
            <pc-button  class="remove-btn" theme="default" icon="trash" kind="flat" (click)="removeItem(i)">
                {{ 'ACTIONS.REMOVE' | translate }}
            </pc-button>
        </div>
        <div class="col-*">        
        </div>
    </div>
  </div>

  <div>

      <pc-button theme="success" icon="check" type="submit" [disabled]="formGroup.invalid" (click)="handleSubmit()">
        {{'ACTIONS.SUBMIT' | translate}}
      </pc-button>

      <pc-button theme="default" icon="times" kind="flat" [link]="cancelLink">
        {{'ACTIONS.CANCEL' | translate}}
      </pc-button>

   </div>
</div>
</form>

以下是我的account-service-provider-clients.component.html

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms';
import { duplicateClientNameValidator, AuthenticationService, ToastService } from '../../shared';
import { ServiceProviderClient, Account} from '../../shared/models'
import { ServiceProviderClientBulkUpdateRequest } from '../../shared/models/requests'
import { ServiceProviderClientService }  from '../../shared/services';
import { take, tap, switchMap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
@Component({
  selector: 'pc-account-service-provider-clients',
  templateUrl: './account-service-provider-clients.component.html',
  styleUrls: ['./account-service-provider-clients.component.scss']
})
export class AccountServiceProviderClientsComponent implements OnInit {

  formGroup: FormGroup;
  isLoading = false;
  account: Account;  
  constructor( private fb: FormBuilder, private serviceProviderClientService: ServiceProviderClientService, private authenticationService: AuthenticationService
      , private translate: TranslateService, private toastService: ToastService) {}

  ngOnInit() {

    this.isLoading = true;
    this.formGroup = this.fb.group({
        aliases: this.fb.array([])
       },{validator: [duplicateClientNameValidator('aliases')]});

       this.authenticationService.currentUser$.pipe(
        take(1),
        tap( user => { this.account  = user.account } ),
        switchMap( () => this.serviceProviderClientService.getAccountServiceProviderClients())
       ).subscribe(
        serviceProviderClients => {
            this.populateForm(serviceProviderClients);
            this.isLoading = false;
          }
       );
  }

  populateForm(serviceProviderClients: ServiceProviderClient[] ) {
    while (this.aliases.length !== 0) {
      this.aliases.removeAt(0);
    }

    for ( const serviceProviderClient of serviceProviderClients) {
      const formGroupNew: FormGroup = new FormGroup( {
          id: new FormControl( { value:serviceProviderClient.id, disabled:false}),
          name: new FormControl({ value:serviceProviderClient.name, disabled:false},[Validators.required, Validators.maxLength(50)]),
          companyNumber: new FormControl({ value:serviceProviderClient.companyNumber, disabled:false},Validators.maxLength(20))
        }
      );
      this.aliases.push(formGroupNew);
    }  
  }

  get aliases() {
    return this.formGroup.get('aliases') as FormArray;
  }

  addAlias() {

    const formGroupNew: FormGroup = new FormGroup( {
          id: new FormControl( { value:'', disabled:false}),
          name: new FormControl({ value:'', disabled:false},[Validators.required, Validators.maxLength(50)]),
          companyNumber: new FormControl({ value:'', disabled:false},Validators.maxLength(20))
      }
    );
    this.aliases.push(formGroupNew);
  }

removeItem( index :number){
    this.aliases.removeAt(index);
}

handleSubmit() {

  const formArrayLength =  this.aliases.length;

  const serviceProviderClientsArray: ServiceProviderClient[] = [];

  let serviceProviderClientUpdateRequest : ServiceProviderClientBulkUpdateRequest;

  for(let i = 0;i<formArrayLength;i++) 
  {
   const itemFrmGroup:FormGroup =  <FormGroup>this.aliases.at(i);

   const serviceProviderClient: ServiceProviderClient = {
     id:  itemFrmGroup.get("id").value,
     name: itemFrmGroup.get("name").value,
     companyNumber:  itemFrmGroup.get("companyNumber").value
   }
   serviceProviderClientsArray.push(serviceProviderClient);
  }

  serviceProviderClientUpdateRequest = {
    clients : serviceProviderClientsArray
  }

  this.isLoading = true;

  this.serviceProviderClientService.bulkUpdate(serviceProviderClientUpdateRequest).subscribe(
    (result) => {
      this.isLoading = false;
      this.populateForm(result);

      this.translate
      .get([
        'VALIDATION.SUCCESS.SERVICE_PROVIDER_CLIENT_SETTINGS.TITLE',
        'VALIDATION.SUCCESS.SERVICE_PROVIDER_CLIENT_SETTINGS.BODY'
      ])
      .subscribe(translate => {
        this.toastService.toast({
          title: translate['VALIDATION.SUCCESS.SERVICE_PROVIDER_CLIENT_SETTINGS.TITLE'],
          body: translate['VALIDATION.SUCCESS.SERVICE_PROVIDER_CLIENT_SETTINGS.BODY'],
          type: 'success',
          icon: 'check-circle'
        });
      });

    },
    ()=> {
      this.isLoading = false;
    }
  );

}

get cancelLink(): string {
  return  '/dashboard';
}

}

我认为表单数组的使用导致了这个问题。 许多网站建议使用 get 方法来访问表单数组,我正在这样做但没有成功

 get aliases() {
    return this.formGroup.get('aliases') as FormArray;
  }

非常感谢任何帮助 太感谢了 普拉桑

我已经解决了如下问题

1) 在我的 ts 文件中创建了如下新方法

 get aliasesArrayControl() {
    return (this.formGroup.get('aliases') as FormArray).controls;
  }

然后在我的控制下按如下方式访问。

<div formArrayName="aliases" *ngFor="let item of aliasesArrayControl; let i = index">
</div>

感谢