用验证器包装角反应形式组件 [英] Wrapping angular reactive form component with validator
问题描述
使用angular 7和Bootstrap 4,我想将bootstrap 4输入包装在一个自定义组件中,以减少模板中的样板.
Working with angular 7 and Bootstrap 4, I want to wrap my bootstrap 4 inputs in a custom component in order to reduce the boilerplate in my templates.
我希望最终的主要组件看起来像这样:
I want that the final main component look like:
<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是这样创建的:
Where my formGroup is created like this:
public createFormGroup() {
return this.fb.group({
firstName: [null, Validators.required],
lastName: [null, Validators.required],
});
}
app-form-control模板应如下所示:
The template of app-form-control should look like this:
<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属性绑定到内部输入字段?如何进行验证?
But I don't know how to write the component (in TypeScript). How do I bind the outer formControlName attribute to the inner input field? How to make validation work?
推荐答案
键"正在使用viewProvider.您使用@Input设置为formControl赋值,请参见
The "key" is using viewProvider. You use a @Input set to give value to a formControl, see stackblitz. The "magic" is that if equal refered to formControl in the "children" or form.get('input1') in the parent
@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;
}
并以这种方式调用组件:
And call the component this way:
<form [formGroup]="myForm" (submit)="submit(myForm.value)">
<app-form-control label="Lastname" placeholder="Lastname" controlName="lastName"></app-form-control>
</form>
更新好吧,(一年后)请考虑一下堆栈闪电错误.当您(单击)按钮时,创建一个新表单:
Update well, (after a year) take account the stackblitz was erroneous. when you (click) in buttons create a new Form:
this.form=this.createForm({note:'lll'})
此中断"了组件和表单之间的关系,因为该关系是关于旧表单的-仅在更改@Input"nameControl"时才更改.因此,正确的方法是使用setValue为表单赋予新值.
This "break" the relationship between the component and the form because the relation is about the older form -only change if change the @Input "nameControl". So the correct is use a setValue to give a new value to the form.
这篇关于用验证器包装角反应形式组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!