[嗨,我在编译项目时遇到错误。我正在使用angular 5和打字稿。
我正在从项目根文件夹提供npm运行版本,以下是我收到的错误。
bash-4.2$ npm run build
> [email protected] 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;
}
非常感谢任何帮助非常感谢Prasanth
我应该使用以下内容
<div [formGroupName]="i" *ngFor="let item of aliases; let i = index">
之前使用的是
<div [formGroupName]="i" *ngFor="let item of formGroup.get('aliases').controls; let i = index">