angular - 用验证器包装角反应形式组件
问题描述
使用 angular 7 和 Bootstrap 4,我想将我的 bootstrap 4 输入包装在自定义组件中,以减少模板中的样板。
我希望最终的主要组件看起来像:
<form [formGroup]="myForm" (submit)="submit(myForm.value)">
<app-form-control label="Lastname" placeholder="Lastname" formControlName="lastName"></app-form-control>
<app-form-control label="Firstname" placeholder="Firstname" formControlName="firstName"></app-form-control>
<button class="pull-right" type="submit">
SUBMIT
</button>
<button (click)="reset()">
RESET
</button>
</form>
我的 formGroup 是这样创建的:
public createFormGroup() {
return this.fb.group({
firstName: [null, Validators.required],
lastName: [null, Validators.required],
});
}
app-form-control 的模板应该是这样的:
<div class="form-group row">
<label class="col-2 col-form-label">{{label}}</label>
<div class="col-10">
<input class="form-control" placeholder="{{placeholder}}" [formControlName]="formControlName" autocomplete="nope"/>
</div>
</div>
但我不知道如何编写组件(在 TypeScript 中)。如何将外部 formControlName 属性绑定到内部输入字段?如何使验证工作?
解决方案
“关键”正在使用 viewProvider。您使用 @Input 集为 formControl 赋予值,请参阅stackblitz。“魔术”是如果相等则引用“孩子”中的 formControl 或父母中的 form.get('input1')
@Component({
selector: 'app-form-control',
template: `
<div class="form-group row">
<label class="col-2 col-form-label">{{label}}</label>
<div class="col-10">
<input class="form-control" placeholder="{{placeholder}}"
[formControl]="formControl" autocomplete="nope"/>
</div>
</div>
<!--you can control the properties of formControl-->
{{formControl.valid}}{{formControl.touched}}}
`,
viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]})
export class HelloComponent {
formControl: FormControl;
constructor(private parentF: FormGroupDirective) { }
@Input()
set controlName(value) {
this.formControl = this.parentF.form.get(value) as FormControl
}
@Input() label: string;
@Input() placeholder: string;
}
并以这种方式调用组件:
<form [formGroup]="myForm" (submit)="submit(myForm.value)">
<app-form-control label="Lastname" placeholder="Lastname" controlName="lastName"></app-form-control>
</form>
更新得很好,(一年后)考虑到 stackblitz 是错误的。当您(单击)按钮创建一个新表单时:
this.form=this.createForm({note:'lll'})
这“破坏”了组件和表单之间的关系,因为这种关系是关于旧表单的——只有在更改@Input“nameControl”时才会改变。所以正确的是使用 setValue 给表单一个新的值。
推荐阅读
- valgrind - 无法解析 valgrind XML 输出
- python - 在 Selenium Wire 中使用代理时无法进行 API 调用
- python - 迭代 Pandas DataFrame 以提取数据
- reactjs - 找不到模块'./builders/flow/createFlowUnionType'
- java - java.lang.StringIndexOutOfBoundsException: 索引 x ,长度 0 没有循环
- php - 正则表达式将 $_POST['x'] 转换为 $_x
- python - pygame 移动矩形 | 不更新
- html - 如何将非托管图像嵌入电子邮件签名 HTML
- java - 如何在 JFrame 的迭代之间使我的 for 循环延迟 1 秒?
- javascript - 在加载组件之前检查 prop 值