如何使用NG_VALUE_ACCESSOR将响应式表单实现为自定义组件? [英] How to implement Reactive Form as custom component using NG_VALUE_ACCESSOR?

查看:415
本文介绍了如何使用NG_VALUE_ACCESSOR将响应式表单实现为自定义组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用NG_VALUE_ACCESSOR的情况下,我确实具有模板驱动形式的自定义组件.它真的很好.现在,我想切换到反应形式. StackBlitz演示

I do have a custom component for template driven form where I use NG_VALUE_ACCESSOR. It works really good. Now I would like to switch to reactive form. StackBlitz Demo

问题在于如何使用反应形式作为自定义组件并传递 formGroupformControlName以及如何将其余的其他属性动态传递给父组件,例如required等.

The issue is that how to use a reactive form as a custom component and pass formGroup and formControlName and also how to pass the rest of the other attributes dynamically to the parent component such as required etc.

据我所知,required属性是在*.component.ts文件中定义的.因此,不可能像模板驱动形式那样在父级中将其动态设置为属性绑定.

The required attribute as fare as I know, is being defined in the *.component.ts file. Therefore it would not be possible to set dynamically in the parent as an attribute binding like in template driven form.

我一直在搜索,但不幸的是没有明显的结果.

I have been searching but unfortunately no significant result.

任何想法如何使用NG_VALUE_ACCESSOR并动态传递属性将反应形式实现为自定义组件?

Any Idea how could I implement reactive form as custom component using NG_VALUE_ACCESSOR and passing attribute dynamically?

推荐答案

真的,我不知道您想要什么.您的自定义表单控件也可以与反应式表单一起使用(请参见您的使用反应式表单的自定义表单控件)

Really I don't know what do you want. Your custom form control work with reactive Forms too (see your custom form control using reactive form)

<form [formGroup]="myForm">
   <app-elements-input formControlName="name" ...>
   </app-elements-input>
</form>
//and 
myForm=new FormGroup(
    {
        name:new FormControl()
    }
  )

有时候,需要知道控件何时无效,被触摸...

Well some times it's necesary know when the control is invalid, touched...

一种简单的方法是将其添加为提供程序NG_VALIDATORS

A easy way is add as provider NG_VALIDATORS

{provide: NG_VALIDATORS,
      useExisting:forwardRef(() => InputComponent), 
       multi: true} 

添加一个变量,例如

control:any=null;

e实现了Validator,将其添加到声明中并创建一个函数来验证我们在其中为"control"赋值的地方

e implements Validator, that's add in the declaration and create a function validate where we give value to "control"

export class InputComponent implements ...,Validator {..}

public validate(c: FormControl) {
  if (!this.control)
    this.control=c;
  return null;
 // return (!this._value && !this.required)?{required:true}:null
}

因此您可以在html中使用类似

So you can use in html some like

<span *ngIf="control?.invalid">*</span>

别忘了指出控件何时被触摸,在示例中,我们可以使用输入的事件(模糊)

Don't forget indicate when the control is touched, in the example, we can use the event (blur) of the input

<input ... (blur)="onTouched()">

如果您想制作一个组件来控制表单组,则只能将fromGroup或formControl作为"@Input()"传递

If you want make a component to control a formgroup it's only pass as `@Input()' the fromGroup or the formControl

<form [formGroup]="myForm">
       <children [argformControl]="myForm.get('name')">
       </children>
</form>
//and
@Input() argformControl:FormControl

<form [formGroup]="myForm">
       <children [argFormGroup]="myForm">
       </children>
</form>
//and
@Input() argFormGroup:FormGroup

更新,例如如果我们有一个像这样的对象数组

Update this allow as, e.g. if we has an array of object like

data=[{name:'name',label:'Name'},{name:'surname',label:'Surname'}]

做些喜欢

<!--I add a "clasic" *ngIf to avoid initialize problems
   It can be placed in the form, or in children-->
<form *ngIf="myForm" [formGroup]="myForm">
   <children [argFormGroup]="myForm" [data]="data">
   </children>
</form>

我们的孩子成为

<div *ngFor="let item of data">
{{item.label}}<input [formControl]="argFormGroup.get(item.name)">
</div>
//and 
 @Input() argFormGroup:FormGroup
 @Input() data:any[]

自定义formControl是一个黑匣子".您发送一个值-一个字符串,一个对象...-,您可以修改该字符串或对象.看起来像一个复杂的输入"(mat-date-picker,例如是自定义表单控件)

A custom formControl is a "black box". You send a value -a string, a object...- and you can modify this string or object. It's look like a "complex input" (a mat-date-picker, e.g. is a custom form control)

这篇关于如何使用NG_VALUE_ACCESSOR将响应式表单实现为自定义组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆