元素隐式具有 'any' 类型,因为类型 'AbstractControl' 没有索引签名。你是想打电话给 'get'?ngtsc(7052)
Element implicitly has an 'any' type because type 'AbstractControl' has no index signature. Did you mean to call 'get'?ngtsc(7052)
我遇到了 'controls'enter image description here enter image description here“对象可能是 'null'.ngtsc(2531)”和“元素隐式具有 'any' 类型的问题,因为类型 'AbstractControl' 没有索引签名。您是要调用 'get' 吗?ngtsc(7052)"
你可以从这个网站得到一个想法https://csharp-video-tutorials.blogspot.com/2018/10/angular-dynamic-forms-tutorial.html我想做什么!我想使用 formArray 来检查验证。您可以在下面的图片中看到整个小时输入都显示验证错误。因为我没有使用formArray。当我实现 formArray 时会在这个地方报错。
一开始我用了这个=> *ngFor="let skill of employeeForm.get('skills').controls; let i = index" 但是controls word显示错误! !!
.HTML
<form [formGroup]="employeeForm">
<div formArrayName="skills" *ngFor="let skill of employeeForm.get('skills')['controls']; let i = index;">
<div class="form-group">
<div class="col-sm-offset-2 col sm-4">
<button type="button" class="btn btn-primary" (click)="addSkillButtonClick()">ADD ROW</button>
</div>
</div>
<p-table [loading]="loading" styleClass="text-sm " [ngClass]="{'p-datatable-is-loading': loading}" [value]="dataSource"
[scrollable]="true" scrollHeight="calc(100% + 2px)" scrollDirection="both">
<ng-template pTemplate="header">
<tr>
<th style="width: 250px;">Project</th>
<th style="width: 250px;">Process</th>
<th style="width: 200px;">Working Hours</th>
<th alignFrozen="right" pFrozenColumn class="p-frozen-column p-frozen-border-left" style="width: 114px;"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-source let-index="rowIndex">
<tr *ngIf="dataSource[index].editing; else viewingMode;" class="editing editing-mode" formGroupName="0">
<td style="width: 250px; overflow: visible" >
<div>
<p-autoComplete appendTo="body" #project name="project" [(ngModel)]="dataSource[index].project_id" [suggestions]="projectSuggestions"
field="name" (onSelect)="handleSelectProject($event, index)"
formControlName="project" class="form-control"
(completeMethod)="handleSearchProject($event, index)" (onFocus)="project.show()" placeholder="Search project">
</p-autoComplete>
</div>
</td>
<td style="width: 250px;">
<div>
<p-dropdown formControlName="process" name="process" [ngStyle]="{ width: '100%' }" [(ngModel)]="dataSource[index].process" [options]="processOptions"
placeholder="Select process">
</p-dropdown>
</div>
</td>
<td style="width: 200px;" class="drg-table_working_hours">
<div ngClass="{'has-error': formErrors.hours }">
<p-inputNumber formControlName="hours" [(ngModel)]="dataSource[index].hour" [id]="'working_hour'+ index" [name]="'working_hour'+ index" [min]="0" [max]="24"
placeholder="00" (blur)="logValidationErrors"></p-inputNumber>
<label for="hours" class="md-2 mb-0 pb-0 mr-2 ml-2">h</label>
</div>
<div>
<p-inputNumber formControlName="minutes" [(ngModel)]="dataSource[index].minutes" [id]="'working_min'+ index" [name]="'working_min'+ index" [min]="0" [max]="59" placeholder="0" ></p-inputNumber>
</div>
<label for="hours" class="md-2 mb-0 pb-0 mr-2 ml-2">m</label>
</td>
<td alignFrozen="right" class="flex-row-reverse p-frozen-column p-frozen-border-left" pFrozenColumn style="width: 114px;">
<button [disabled]="dataSource[index].deleting" pButton type="button" (click)="handleDeleteRowClick(index)" icon="pi pi-trash"
class="p-button-link p-button-plain p-button-rounded p-button-outlined"></button>
<button pButton type="button" (click)="handleSaveRowClick(index)" icon="pi pi-save"
class="p-button-link p-button-plain p-button-rounded p-button-outlined mr-1"></button>
</td>
</tr>
</ng-template>
</p-table>
</div>
</form>
.TS
export class DailyReportRegularTableComponent extends DailyReportLog implements OnInit {
@Input() dataSource: UIDailyLogRegularTableInterface[] = [];
@Output() dataSourceChange = new EventEmitter<UIDailyLogRegularTableInterface[]>();
helper!: HelperService
_formHelper: FormService = new FormService;
employeeForm!: FormGroup;
formErrors: any;
validationMessages: any;
constructor(private _helper: HelperService,private formBuilder: FormBuilder,private fb: FormBuilder) {
super();
this.helper = this._helper;
}
ngOnInit(): void {
this.employeeForm = this.fb.group({
skills: this.fb.array([
this.addSkillFormGroup()
])
});
this.employeeForm.valueChanges.subscribe((data) => {
this.logValidationErrors(this.employeeForm)
});
}
addSkillButtonClick(): void {
(<FormArray>this.employeeForm.get('skills')).push(this.addSkillFormGroup());
}
logValidationErrors(group: FormGroup = this.employeeForm): void{
Object.keys(group.controls).forEach((key: string) =>{
const abstractControl = group.get(key)
if(abstractControl instanceof FormGroup){
this.logValidationErrors(abstractControl)
} else {
this.formErrors[key] = '';
if(abstractControl && !abstractControl.valid){
for (const errorKey in abstractControl.errors) {
if (errorKey) {
this.formErrors[key];
}
}
}
if (abstractControl instanceof FormGroup) {
this.logValidationErrors(abstractControl);
}
if (abstractControl instanceof FormArray) {
for (const control of abstractControl.controls){
if (control instanceof FormGroup) {
this.logValidationErrors(control)
}
}
}
}
})
}
addSkillFormGroup(): FormGroup{
return this.fb.group({
project: ['', Validators.required],
process: ['', Validators.required],
hours: ['', Validators.required],
minutes: [''],
})
}
OnLoadDataClick(): void{
this.logValidationErrors(this.employeeForm)
}
}
这是严格的类型检查,将 employeeForm.get('skills')
视为 any
,这是正确的,因为您没有给它指定类型。我建议制作一个 getter 并在其中指定类型:
get skillArr() {
return this.employeeForm.get('skills') as FormArray
}
并在模板中使用:
let skill of skillArr.controls
现在 Angular 可以看出它是一个 formArray。您也可以在模板中将其键入为 any
,但由于您可以将其键入为 FormArray,因此我建议您这样做。这将是将其键入 any
:
的方式
let skill of $any(employeeForm.get('skills')).controls
只有当我在 FormArray 中有一个嵌套的 FormArray 时,我才求助于此,因为使用 getter 是行不通的。
我遇到了 'controls'enter image description here enter image description here“对象可能是 'null'.ngtsc(2531)”和“元素隐式具有 'any' 类型的问题,因为类型 'AbstractControl' 没有索引签名。您是要调用 'get' 吗?ngtsc(7052)"
你可以从这个网站得到一个想法https://csharp-video-tutorials.blogspot.com/2018/10/angular-dynamic-forms-tutorial.html我想做什么!我想使用 formArray 来检查验证。您可以在下面的图片中看到整个小时输入都显示验证错误。因为我没有使用formArray。当我实现 formArray 时会在这个地方报错。
一开始我用了这个=> *ngFor="let skill of employeeForm.get('skills').controls; let i = index" 但是controls word显示错误! !!
.HTML
<form [formGroup]="employeeForm">
<div formArrayName="skills" *ngFor="let skill of employeeForm.get('skills')['controls']; let i = index;">
<div class="form-group">
<div class="col-sm-offset-2 col sm-4">
<button type="button" class="btn btn-primary" (click)="addSkillButtonClick()">ADD ROW</button>
</div>
</div>
<p-table [loading]="loading" styleClass="text-sm " [ngClass]="{'p-datatable-is-loading': loading}" [value]="dataSource"
[scrollable]="true" scrollHeight="calc(100% + 2px)" scrollDirection="both">
<ng-template pTemplate="header">
<tr>
<th style="width: 250px;">Project</th>
<th style="width: 250px;">Process</th>
<th style="width: 200px;">Working Hours</th>
<th alignFrozen="right" pFrozenColumn class="p-frozen-column p-frozen-border-left" style="width: 114px;"></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-source let-index="rowIndex">
<tr *ngIf="dataSource[index].editing; else viewingMode;" class="editing editing-mode" formGroupName="0">
<td style="width: 250px; overflow: visible" >
<div>
<p-autoComplete appendTo="body" #project name="project" [(ngModel)]="dataSource[index].project_id" [suggestions]="projectSuggestions"
field="name" (onSelect)="handleSelectProject($event, index)"
formControlName="project" class="form-control"
(completeMethod)="handleSearchProject($event, index)" (onFocus)="project.show()" placeholder="Search project">
</p-autoComplete>
</div>
</td>
<td style="width: 250px;">
<div>
<p-dropdown formControlName="process" name="process" [ngStyle]="{ width: '100%' }" [(ngModel)]="dataSource[index].process" [options]="processOptions"
placeholder="Select process">
</p-dropdown>
</div>
</td>
<td style="width: 200px;" class="drg-table_working_hours">
<div ngClass="{'has-error': formErrors.hours }">
<p-inputNumber formControlName="hours" [(ngModel)]="dataSource[index].hour" [id]="'working_hour'+ index" [name]="'working_hour'+ index" [min]="0" [max]="24"
placeholder="00" (blur)="logValidationErrors"></p-inputNumber>
<label for="hours" class="md-2 mb-0 pb-0 mr-2 ml-2">h</label>
</div>
<div>
<p-inputNumber formControlName="minutes" [(ngModel)]="dataSource[index].minutes" [id]="'working_min'+ index" [name]="'working_min'+ index" [min]="0" [max]="59" placeholder="0" ></p-inputNumber>
</div>
<label for="hours" class="md-2 mb-0 pb-0 mr-2 ml-2">m</label>
</td>
<td alignFrozen="right" class="flex-row-reverse p-frozen-column p-frozen-border-left" pFrozenColumn style="width: 114px;">
<button [disabled]="dataSource[index].deleting" pButton type="button" (click)="handleDeleteRowClick(index)" icon="pi pi-trash"
class="p-button-link p-button-plain p-button-rounded p-button-outlined"></button>
<button pButton type="button" (click)="handleSaveRowClick(index)" icon="pi pi-save"
class="p-button-link p-button-plain p-button-rounded p-button-outlined mr-1"></button>
</td>
</tr>
</ng-template>
</p-table>
</div>
</form>
.TS
export class DailyReportRegularTableComponent extends DailyReportLog implements OnInit {
@Input() dataSource: UIDailyLogRegularTableInterface[] = [];
@Output() dataSourceChange = new EventEmitter<UIDailyLogRegularTableInterface[]>();
helper!: HelperService
_formHelper: FormService = new FormService;
employeeForm!: FormGroup;
formErrors: any;
validationMessages: any;
constructor(private _helper: HelperService,private formBuilder: FormBuilder,private fb: FormBuilder) {
super();
this.helper = this._helper;
}
ngOnInit(): void {
this.employeeForm = this.fb.group({
skills: this.fb.array([
this.addSkillFormGroup()
])
});
this.employeeForm.valueChanges.subscribe((data) => {
this.logValidationErrors(this.employeeForm)
});
}
addSkillButtonClick(): void {
(<FormArray>this.employeeForm.get('skills')).push(this.addSkillFormGroup());
}
logValidationErrors(group: FormGroup = this.employeeForm): void{
Object.keys(group.controls).forEach((key: string) =>{
const abstractControl = group.get(key)
if(abstractControl instanceof FormGroup){
this.logValidationErrors(abstractControl)
} else {
this.formErrors[key] = '';
if(abstractControl && !abstractControl.valid){
for (const errorKey in abstractControl.errors) {
if (errorKey) {
this.formErrors[key];
}
}
}
if (abstractControl instanceof FormGroup) {
this.logValidationErrors(abstractControl);
}
if (abstractControl instanceof FormArray) {
for (const control of abstractControl.controls){
if (control instanceof FormGroup) {
this.logValidationErrors(control)
}
}
}
}
})
}
addSkillFormGroup(): FormGroup{
return this.fb.group({
project: ['', Validators.required],
process: ['', Validators.required],
hours: ['', Validators.required],
minutes: [''],
})
}
OnLoadDataClick(): void{
this.logValidationErrors(this.employeeForm)
}
}
这是严格的类型检查,将 employeeForm.get('skills')
视为 any
,这是正确的,因为您没有给它指定类型。我建议制作一个 getter 并在其中指定类型:
get skillArr() {
return this.employeeForm.get('skills') as FormArray
}
并在模板中使用:
let skill of skillArr.controls
现在 Angular 可以看出它是一个 formArray。您也可以在模板中将其键入为 any
,但由于您可以将其键入为 FormArray,因此我建议您这样做。这将是将其键入 any
:
let skill of $any(employeeForm.get('skills')).controls
只有当我在 FormArray 中有一个嵌套的 FormArray 时,我才求助于此,因为使用 getter 是行不通的。