angular - 如何禁用子组件(子表单组)?
问题描述
我有:
- 主要组件(也是主要的formGoup)- register-form
- 子组件(也是子 formGoup) - 行
如您所见,我的主表单(没有子表单)处于禁用状态,您可以通过单击编辑按钮启用它。我也希望子组件是这样的。因此,整个表单被禁用,并且在单击编辑按钮时它被启用(您可以键入、选择等)。我该怎么做?我试过做这样的事情:
constructor(private formBuilder: FormBuilder) {
this.registerForm = this.formBuilder.group({
username: [{value: '', disabled: this.disableForm}],
email: [{value: '', disabled: this.disableForm}],
password: [{value: '', disabled: this.disableForm}],
confirmpassword: [{value: '', disabled: this.disableForm}],
dropdown: [{value: '', disabled: this.disableForm}],
checkbox1: [{value: '', disabled: this.disableForm}],
rowForm: this.formBuilder.group(
{
input1: [''],
input2: [''],
input3: [''],
checkbox2: ['']
}
)
});
}
但它根本不起作用。
我的注册表单(主要组件,主要表单组)html文件:
<div class="main-wrapper" fxLayout="row" fxLayoutAlign="center center">
<mat-card class="box">
<mat-card-header class="header">
<mat-card-title>Register</mat-card-title>
</mat-card-header>
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<mat-checkbox class="example-margin" [formControl]="checkbox1">Show hidden option!</mat-checkbox>
<!-- Username -->
<mat-card-content>
<mat-form-field class="example-full-width">
<input matInput placeholder="Username" name="username" minlength="5"
formControlName="username" required>
</mat-form-field>
<mat-error *ngIf="username.touched && !username.valid">
<div *ngIf="username.errors?.required">Username is required.</div>
<div *ngIf="username.errors?.minlength">Username should be minimum 5 characters.</div>
</mat-error>
<!-- Email -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Email" name="email" minlength="5" [pattern]="emailPattern"
formControlName="email" required>
</mat-form-field>
<mat-error *ngIf="email.touched && !email.valid">
<div *ngIf="email.errors?.required">Email is required.</div>
<div *ngIf="email.errors?.pattern">Email is not valid.</div>
</mat-error>
<!-- Password -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Password" name="password" minlength="5"
formControlName="password" required>
</mat-form-field>
<mat-error *ngIf="password.touched && !password.valid">
<div *ngIf="password.errors?.required">Password is required.</div>
<div *ngIf="password.errors?.minlength">Password should be minimum 5 characters.</div>
</mat-error>
<!-- Repeat Password -->
<mat-form-field class="example-full-width">
<input matInput placeholder="Confirm Password" name="confirmpassword" formControlName="confirmpassword"
required>
</mat-form-field>
<mat-error *ngIf="confirmpassword.touched && confirmpassword.value != password.value"> Passwords does not match
</mat-error>
</mat-card-content>
<app-row [rowForm]="registerForm.controls.rowForm"></app-row>
<button mat-button color="primary" class="btn-block" *ngIf="isEditable; else edit" type="submit"
[disabled]="!registerForm.valid"> Register
</button>
<ng-template #edit>
<button mat-button color="primary" class="btn-block" type="button" (click)="enableEdit()">
Edit
</button>
</ng-template>
</form>
</mat-card>
我的注册表单(主要组件,主要表单组)ts文件:
import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'app-register-form',
templateUrl: './register-form.component.html',
styleUrls: ['./register-form.component.css']
})
export class RegisterFormComponent implements OnInit {
emailPattern = '^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$';
registerForm;
disableForm = true;
isEditable;
constructor(private formBuilder: FormBuilder) {
this.registerForm = this.formBuilder.group({
username: [{value: '', disabled: this.disableForm}],
email: [{value: '', disabled: this.disableForm}],
password: [{value: '', disabled: this.disableForm}],
confirmpassword: [{value: '', disabled: this.disableForm}],
checkbox1: [{value: '', disabled: this.disableForm}],
rowForm: this.formBuilder.group(
{
input1: [{value: '', disabled: this.disableForm}],
input2: [{value: '', disabled: this.disableForm}],
input3: [{value: '', disabled: this.disableForm}],
checkbox2: [{value: '', disabled: this.disableForm}]
}
)
});
}
ngOnInit(): void {
}
enableEdit() {
this.disableForm = !this.disableForm;
this.registerForm.enable();
this.isEditable = true;
}
get username() {
return this.registerForm.get('username');
}
get email() {
return this.registerForm.get('email');
}
get password() {
return this.registerForm.get('password');
}
get confirmpassword() {
return this.registerForm.get('confirmpassword');
}
get checkbox1() {
return this.registerForm.get('checkbox1');
}
onSubmit() {
console.log(this.registerForm.value);
this.registerForm.disable();
this.isEditable = false;
}
}
我的行(子组件,子表单组)html文件:
<form [formGroup]="rowForm">
<div formArrayName="rows">
<div *ngFor="let rows of getControls(); let i=index" [formGroupName]="i">
<mat-checkbox class="example-margin" formControlName="checkbox2" name="checkbox2" (click)="toggleInput()">Show hidden option!</mat-checkbox>
<mat-form-field class="example-full-width">
<input matInput placeholder="Input1" formControlName="input1" name="input1" required>
</mat-form-field>
<mat-form-field class="example-full-width">
<input matInput placeholder="Input2" formControlName="input2" name="input2" required>
</mat-form-field>
<mat-form-field *ngIf="showInput" class="example-full-width">
<input matInput placeholder="Input3" formControlName="input3" name="input3" required>
</mat-form-field>
<button mat-button color="primary" *ngIf="rowForm.controls.rows.controls.length > 1" (click)="deleteRow(i)" class="btn btn-danger">Delete Button</button>
</div>
</div>
<button mat-button color="primary" (click)="addNewRow()" class="btn btn-primary">Add new Row</button><br>
</form>
我的行(子组件,子表单组)ts文件:
import {Component, Input, OnInit} from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators, FormArray} from '@angular/forms';
@Component({
selector: 'app-row',
templateUrl: './row.component.html',
styleUrls: ['./row.component.css']
})
export class RowComponent implements OnInit {
@Input() rowForm: FormGroup;
showInput = false;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.rowForm = this.formBuilder.group({
rows: this.formBuilder.array([this.createRow()])
});
}
createRow(): FormGroup {
return this.formBuilder.group({
input1: ['', Validators.required],
input2: ['', Validators.required],
input3: ['', Validators.required],
checkbox2: ['', Validators.required],
});
}
toggleInput(index: number) {
this.showInput = !this.showInput;
}
get formArray() {
return this.rowForm.get('rows') as FormArray;
}
// Adding row function
addNewRow() {
this.formArray.push(this.createRow());
}
deleteRow(index: number) {
this.formArray.removeAt(index);
}
getControls() {
return (this.rowForm.get('rows') as FormArray).controls;
}
}
解决方案
它有点旧,但我喜欢使用指令禁用 FormControl
否则,您可以创建一个禁用/启用 formGroup 及其子项的函数
enable(form: FormGroup, enable: boolean) {
Object.keys(form.controls).forEach(key => {
const control = form.get(key);
if (control) {
if ((control as any).controls)
this.enable(control as FormGroup, enable);
else {
if (enable) control.enable();
else control.disable();
}
}
});
}
使用指令将指令添加到每个输入并使用变量,例如
<input matInput [enableControl]="toogle" placeholder="Ex. Pizza" formControlName="prop1">
每次更改指令时,输入都会被禁用/启用
该功能在您的 .ts 中,在您的“编辑”按钮中
<button (click)="enable(registerForm,true)">Edit</button>
但是您的代码中有一些错误。管理嵌套表单有多种方法。
1.-更简单的方法是在父级中创建表单并将“formGroup”传递给子级。但你做错了。创建 registerForm 时需要更改
this.registerForm = this.formBuilder.group({
username: [{value: '', disabled: this.disableForm}],
email: [{value: '', disabled: this.disableForm}],
password: [{value: '', disabled: this.disableForm}],
confirmpassword: [{value: '', disabled: this.disableForm}],
checkbox1: [{value: '', disabled: this.disableForm}],
rowForm: this.formBuilder.group({
rows:this.formBuilder.array([this.createRow(true)])
})
});
createRow(disabled:boolean=false): FormGroup {
return this.formBuilder.group({
input1: [{value:'',disabled:disabled}, Validators.required],
input2: [{value:'',disabled:disabled}, Validators.required],
input3: [{value:'',disabled:disabled}, Validators.required],
checkbox2: [{value:'',disabled:disabled}, Validators.requiredTrue],
});
}
看到你是在 formArray 中创建元素的重复代码 - 你的孩子中有另一个类似的 - 我更改了一些函数来创建禁用的控件。
2.-创建一个 FromGroup 空并在 child 中添加 formGroup。为此,我们将表单组“rowForm”创建为 FromGroup 空
this.registerForm = this.formBuilder.group({
username: [{value: '', disabled: this.disableForm}],
....
rowForm: this.formBuilder.group({})
});
在孩子中,我们在 ngOnInit 中“更改”这个 formGroup。我包含在 setTimeout() 中以避免错误“ExpressionChangedAfterItHasBeenCheckedError”
ngOnInit() {
setTimeout(()=>{
this.rowForm.addControl("rows",this.formBuilder.array([this.createRow(true)]))
})
}
使用这种方法,您无需重复代码
这样就可以使用我在代码中写的启用功能了。
在这个 stackblitz中,有第一个选项(在父级中创建整个表单)
在这个 stackbliz中是第二个(在 child 中创建 rowForm 并添加到 parent)
(*)为避免重复代码,您可以使用 ViewChild 来获取子项并使用子项的函数“createRow”
推荐阅读
- python - 如何在 python 中使用客户端服务器连接云虚拟机
- dji-sdk - 如何打开 DJI SDK 系统日志?
- python - 为 Flask Web 应用程序创建 Docker 容器时出现问题
- algorithm - KMP 的 Leetcode 459 证明
- reactjs - 如何将对象从 React.js 传递到 Controller API?
- reactjs - 如何在material-ui中进行分组自动完成
- python - 为python设置虚拟环境
- java - 使用 Jackson 编写和读取资源文件
- javascript - 为什么这个数组被认为是一个对象,以及如何处理它?
- r - 关于在 R 中拟合分类树的问题