元素隐含地具有“任何”类型,因为类型“AbstractControl”没有索引签名。您的意思是调用“get”吗?ngtsc(7052)

Posted

技术标签:

【中文标题】元素隐含地具有“任何”类型,因为类型“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) 【发布时间】:2022-01-16 15:34:51 【问题描述】:

我遇到了 '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" 但是控制字显示为错误!!!

.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)
  


【问题讨论】:

解释您在此处尝试执行的操作,而不是链接网站网址。如果站点 url 稍后在此问题上被破坏,社区将不会使用。 现在清楚了吗@VimalPatel? 【参考方案1】:

这是严格的类型检查并将employeeForm.get('skills') 视为any,这是正确的,因为您没有给它一个类型。我建议您在其中指定类型的吸气剂:

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 是行不通的。

【讨论】:

以上是关于元素隐含地具有“任何”类型,因为类型“AbstractControl”没有索引签名。您的意思是调用“get”吗?ngtsc(7052)的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript Err:“元素隐式具有‘any’类型,因为‘any’类型的表达式不能用于索引类型

打字稿“新”表达式,其目标缺少构造签名,隐含具有“任何”类型

元素隐式具有“任何”类型,因为类型“窗口”没有索引签名?

元素隐式具有“任何”类型,因为类型的表达式

使用键名索引 json 对象给出错误 [[keyname]] 不能用于索引类型“对象”

元素隐式具有“任何”类型,因为类型的表达式