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>
但是当我在任何按钮点击或提交时执行相同的代码时,它可以正常工作。
问题:如何在表单初始化后禁用其中一个字段?
我不是这个的粉丝,但是这个 "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
里面也可以
我有一个页面,其中有一个简单的 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>
但是当我在任何按钮点击或提交时执行相同的代码时,它可以正常工作。
问题:如何在表单初始化后禁用其中一个字段?
我不是这个的粉丝,但是这个 "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
里面也可以