Angular - NgForm - FormControl 未定义

Angular - NgForm - FormControl is undefined

我有一个页面,其中有一个简单的 NgForm 表单,我试图在加载 page/view 后禁用特定字段。

但是我遇到了未定义的异常:

ERROR TypeError: Cannot read property 'disable' of undefined

component.ts代码:

import { Component, ViewChild, OnInit, AfterViewInit } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
  selector: 'sub',
  templateUrl: 'sub.component.html'
})

export class SubComponent implements OnInit, AfterViewInit {
  @ViewChild('userForm') uf: NgForm;

  ngOnInit() {
    console.log(this.uf);
    console.log(this.uf.controls['name']) // this is null
  }

  ngAfterViewInit() {
    console.log('kasdkfj')
    console.log(this.uf);
    console.log(this.uf.controls['name']) // this is null 
            this.uf.controls['name'].disable(); // Exception here
  }

  onSubmit(value: any) {
    console.log(this.uf.controls['name']) // But this is NOT null
            this.uf.controls['name'].disable(); // NO Exception, works perfectly
    console.log(value); 
  }
}

HTML代码:

<div class="container">
  <h2>Form Data</h2>

      <form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value)">
       <div class="form-group"> 
             <label>Name</label>
              <input type="text" class="form-control" name="name" ngModel> 
        </div><br/>
        <div ngModelGroup="address">
              <div class="form-group"> 
                  <label>City</label>
                    <input type="text" class="form-control" name="city" ngModel> 
              </div><br/>
              <div class="form-group"> 
                  <label>Pin</label>
                    <input type="text" class="form-control" name="pin" ngModel> 
              </div><br/>
              <div class="form-group"> 
                  <label>State</label>
                    <input type="text" class="form-control" name="state" ngModel> 
              </div><br/>

        </div>
       <button type="submit" class="btn btn-primary" >Submit</button>
      </form>
  </div>

但是当我在任何按钮点击或提交时执行相同的代码时,它可以正常工作。

问题:如何在表单初始化后禁用其中一个字段?

Stackblitz Link

我不是这个的粉丝,但是这个 "fixes" 问题。

ngAfterViewInit() {
    setTimeout(() => {
      console.log(this.uf.controls['name']) // this is null
      this.uf.controls['name'].disable(); // Exception here
    }, 0);
  }

您可以将其包装在 setTimeout() 中以强制执行,或者您可以使用 NgZone (for dirty check)

ngAfterViewInit() {
    setTimeout( () => {
      this.uf.controls['name'].disable();
    })
}

我认为,主要原因是您构建表单的方式有误。查看有关 Reactive Forms 的文档。你应该在组件中构建你的表单 controls/groups 而不是试图通过 @ViewChild

检索它们和表单本身

您可以将以下指令添加到输入元素,并将其绑定到组件中的变量。

<input type="text" class="form-control" name="name" ngModel [disabled]="nameDisabled">

如您在 sources 中所见,ngModel 在宏任务 (resolvedPromise.then(...)) 的父级(以及其他 ngModels 反应)中注册。完成这些处理是因为 ngModel 可以导出为,并且通过参数的更改应该更改组件内部,然后反映回父模板。

在模板驱动的表单中,只需将 disabled 属性添加到您想要在初始化时禁用的表单字段,就像这样 <input type="text" class="form-control" name="name" ngModel disabled>。别担心,它只会在元素创建时 "applied" 一次,不会影响未来的行为。

如果你不喜欢上面的方法 Promise.resolve().then(() => this.uf.controls['name'].disable())ngAfterViewInit 里面也可以