以下是我如何在表单中执行此操作(请记住,我使用的是带有表单生成器的反应式表单,而不是带有 ngModel 的模板驱动表单):
First,我在名为的目录中创建一个自定义 FormModuleforms
.
Next,里面有各种表单组件。让我们使用LoginFormComponent
例如。
这里是LoginFormComponent
:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'login-form',
templateUrl: './login-form.component.html'
})
export class LoginFormComponent implements OnInit {
@Output() onChange: EventEmitter<FormGroup> = new EventEmitter();
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
email: [null, Validators.email],
password: [null, [Validators.required, Validators.minLength(6), Validators.maxLength(60)]]
});
this.form.valueChanges.subscribe(() => this.onChange.emit(this.form));
}
ngOnInit() {
this.onChange.emit(this.form);
}
}
这是 HTML:
<form autocomplete="off" [formGroup]="form">
<div class="form-group">
<label for="username">Email *</label>
<input type="text" id="username" class="form-control" placeholder="Enter your email address" formControlName="email" autofocus>
<control-messages [control]="form.get('email')"></control-messages>
</div>
<label for="password">Password *</label>
<input type="password" id="password" class="form-control" placeholder="Enter your password" formControlName="password">
<control-messages [control]="form.get('password')" [label]="'Password'"></control-messages>
</form>
现在在导入模块内的任何自定义组件中FormModule
,我可以执行以下操作:
应用程序组件.html:
<login-form (onChange)="form = $event"></login-form>
<button (click)="submit()">Submit</button>
应用程序组件.ts:
@Component({...})
export class AppComponent {
form: FormGroup;
submit() {
// Do something with `this.form`.
}
}
这种设计的好处可能不会立即显现出来,但它使我们能够做一些事情:
- 首先,我们可以重用
login-form
只要我们导入我们的自定义组件,就可以在我们应用程序的任何位置FormModule
。如果我们更改它,它会在各处自动更新。保持事物干燥。
- 接下来,我们可能不希望每个地方都有相同的提交按钮/文本,并且我们可能希望它在不同的位置执行不同的操作,因此
login-form
组件仅包含表单本身,任何提交逻辑都在其外部处理以实现重用。当您拥有用于创建和编辑的表单时,这一点很重要。编辑按钮可以保存数据,而创建按钮可以创建新内容。如果将提交按钮放在表单组件内,则这种重用并不容易实现。
对于稍微复杂的表单,比如说可以接受一些默认值的表单,请看一下这个示例TagFormComponent
:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Tag } from 'shared';
@Component({
selector: 'tag-form',
templateUrl: './tag-form.component.html'
})
export class TagFormComponent implements OnInit {
@Output() onChange: EventEmitter<FormGroup> = new EventEmitter();
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
name: [null, Validators.email]
});
this.form.valueChanges.subscribe(() => {
this.onChange.emit(this.form);
});
}
@Input()
set tag(tag: Tag) {
if (tag) {
this.form.patchValue(tag);
}
}
ngOnInit() {
this.onChange.emit(this.form);
}
}
这遵循与LoginFormComponent
,除了这个可以传递表单的一些默认值。像这样:
<tag-form [tag]="tag" (onChange)="form = $event"></tag-form>