【问题标题】:Getting error after upgrading from Angular 8 to 12 - "Property 'controls' does not exist on type 'AbstractControl' "从 Angular 8 升级到 12 后出现错误 - “‘AbstractControl’ 类型上不存在属性‘控件’”
【发布时间】:2021-11-21 14:42:03
【问题描述】:

我在 Angular 8 中有一个功能齐全的代码。我决定从 Angular 8 升级到 Angular 12。

我有一个动态反应形式。形式为问答形式。 根据谁在登录,问题会发生变化。答案是是/否格式。基于谁在登录以及选择了什么答案选项文本框下拉和复选框或所有提到的应用程序。

这是我的表单代码

Component.ts

constructor(
    private router: Router,
    private datePipe: DatePipe,
    private route: ActivatedRoute,
    private formBuilder: FormBuilder) {      
    this.dynamicForm = this.formBuilder.group({
        questions: new FormArray([])
    });
    this.CreateForm();
}

get f() { return this.dynamicForm.controls; }
get t() { return this.f.questions as FormArray; }


CreateForm() {
    if (this.formdetail.questionList) {
        // CREATE Questions
        if (racialQues !==  this.formdetail.questionList[i].quetext && this.formdetail.questionList[i].quetext !== auditQues) {
            this.t.push(this.formBuilder.group({
                quesIndex: [i + 1],
                ...
                controlName: [this.formdetail.questionList[i].selectedAns, [Validators.required]]
            }));
        } else if (this.formdetail.questionList[i].quetext === auditQues) {
            this.t.push(this.formBuilder.group({
                quesIndex: [i + 1],
                ......
                selectedValue: [this.formdetail.auditTrail.selectedValue, this.reasonValidator],
            }));
        } else if (this.formdetail.questionList[i].quetext === racialQues) {
      
            this.t.push(this.formBuilder.group({
                quesIndex: [i + 1],
                ......
                selectedAuxAns: [this.formdetail.questionList[i].val, [this.auxAnsValidator]]
            }));
        }
    }
}

这里是html

<form [formGroup]="dynamicForm"> 
<!--  Question Start -->
<div *ngFor="let ticket of t.controls; let i = index">
    <div [formGroup]="ticket" class="form-row">  
        <div class="input-group col-md-12" style="padding: .15em .5em">                                        
            <div class="input-group-prepend col-md-10" style="padding: 0; margin: 0;">                
                <label class="input-group-text w-15">{{i + 1}}</label>
                <label class="input-group-text w-100" style="text-align: left; white-space: normal;">{{ticket.controls.name.value}}</label>
            </div>                                 
            <select formControlName="controlName" class="form-control col-md-2" style="height:auto !important;" 
                [ngClass]="{ 'is-invalid': submitted && ticket.controls.controlName.errors }"
                (change)="onChange($event.target.value, i)">
                <option [ngValue]="null"> --Select-- </option>
                <option *ngFor="let ansItem of formdetail.questionList[i].answerList" [ngValue]="ansItem" >{{ansItem.anstext}}</option>
            </select>
            <div *ngIf="submitted && ticket.controls.controlName.errors" class="invalid-feedback" style="height:auto !important;" 
            [ngClass]="{ 'input-group-append': submitted && ticket.controls.controlName.errors,
                         'col-md-1': submitted && ticket.controls.controlName.errors }">
                <div *ngIf="ticket.controls.controlName.errors.required">Required</div>
            </div>
            .
            .
            .
            .
            
        </div>  
    /div>
</div>     
<!--  Question End -->                
</form>    

现在我在“ticket.control”中遇到错误

“AbstractControl”类型上不存在属性“控件”。

我不确定升级后为什么会出现此错误。 我已经尝试过ticket.['control']ticket.get('controlName'),正如stackoverflow 中其他类似错误的文章所建议的那样,但没有任何效果

这是错误的快照

任何帮助将不胜感激。 谢谢

【问题讨论】:

    标签: html angular typescript


    【解决方案1】:

    您的tFormArray 类型,FormArray.controls 数组是AbstractControl[] 类型,因此,每个ticket

    <div *ngFor="let ticket of t.controls; let i = index">
    

    行的类型为AbstractControl,它没有controls 属性,如屏幕截图中的TS 错误所示。 TS 不知道每个ticket 实际上是FormGroup 类型(在此处设置this.t.push(this.formBuilder.group({...}) 并具有controls property)。

    所以你可以尝试添加另一个getter tControls

    get f() { return this.dynamicForm.controls; }
    get t() { return this.f.questions as FormArray; }
    get tControls() { return this.t.controls as FormGroup[]; }
    

    并在*ngFor中使用它:

    <div *ngFor="let ticket of tControls; let i = index">
        <div [formGroup]="ticket" class="form-row">
        ...
    

    请注意,现在[formGroup] 也将正确填充为FormGroup 而不是AbstarctControl

    您的一个 Angular 升级可能已添加

    "angularCompilerOptions": {
      "fullTemplateTypeCheck": true,
      "strictInputTypes": true,
    }
    

    到您的 tsconfig.json 文件,您可以通过将这些值设置为 false 并重新构建您的应用来验证它,但我建议保留这些严格的检查。

    【讨论】:

    • 谢谢@Andriy。我试过这个 get tControls { return this.t.controls ;它给了我同样的抽象控制错误。解析是关键。感谢您的帮助
    【解决方案2】:

    这是帮助解决此类问题的通用答案(通用代码)。 假设您有一个循环遍历 FormArray 类型的字段(称为元素)。该字段是 FormGroup 类型表单的一部分

    在您的 ts 逻辑代码(逻辑实现)中,您应该有类似的内容:

      form = new FormGroup({
       //.. other fields
        elements: new FormArray([]),
      });
    

    在您的模板(html 文件)中,您需要遍历元素字段:

    <li
      *ngFor="let element of elements.controls">
      {{ element.value }}
    </li>
    

    为了告诉 Angular cli 元素具有控件的属性(因此是 FormArray 类型),您需要在 ts 逻辑代码中将其格式化如下(为元素字段实现 getter):

      get elements() {
        return this.form.get('elements') as FormArray;
      }
    

    【讨论】:

      【解决方案3】:

      'controls' 不是property of an AbstractControl。相反,您可以使用表单组,因此 'dynamicForm.controls.controlName'

      【讨论】:

      • 你有什么例子吗?
      猜你喜欢
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 2023-03-03
      • 2018-01-26
      • 2021-08-13
      • 1970-01-01
      相关资源
      最近更新 更多