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

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

问题描述

我确实有一个用于模板驱动表单的自定义组件,我在其中使用了 NG_VALUE_ACCESSOR.它真的很好用.现在我想切换到反应式.StackBlitz 演示

问题是如何使用响应式表单作为自定义组件并通过formGroupformControlName 以及如何将其余的其他属性动态传递给父组件,例如 required

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

我一直在寻找,但不幸的是没有显着的结果.

知道如何使用 NG_VALUE_ACCESSOR 和动态传递属性将反应式表单实现为自定义组件吗?

解决方案

我真的不知道你想要什么.您的自定义表单控件也适用于响应式表单(请参阅 您的使用响应式表单的自定义表单控件)

<app-elements-input formControlName="name" ...></app-elements-input></表单>//和myForm=新的FormGroup({名称:新表单控件()})

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

一种简单的方法是添加为提供者 NG_VALIDATORS

{提供:NG_VALIDATORS,useExisting:forwardRef(() => InputComponent),多:真}

添加一个变量,例如

control:any=null;

e 实现了 Validator,即在声明中添加并创建一个函数 validate,我们将值赋予控制"

导出类 InputComponent 实现 ...,Validator {..}公共验证(c:FormControl){如果(!this.control)this.control=c;返回空;//返回 (!this._value && !this.required)?{required:true}:null}

所以你可以在html中使用一些

*

不要忘记在控件被触摸时进行指示,在示例中,我们可以使用输入的事件(模糊)

如果你想制作一个组件来控制一个表单组,它只能作为`@Input()' fromGroup 或 formControl 传递

<children [argformControl]="myForm.get('name')"></儿童></表单>//和@Input() argformControl:FormControl

<children [argFormGroup]="myForm"></儿童></表单>//和@Input() argFormGroup:FormGroup

更新这允许,例如如果我们有一个像

这样的对象数组

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

做一些喜欢

<!--我添加了经典" *ngIf 以避免初始化问题它可以放在表格中,也可以放在儿童中--><form *ngIf="myForm" [formGroup]="myForm"><children [argFormGroup]="myForm" [data]="data"></儿童></表单>

我们的孩子变成了

{{item.label}}

//和@Input() argFormGroup:FormGroup@Input() 数据:任何[]

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

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

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.

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.

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...

A easy way is add as provider NG_VALIDATORS

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

Add one variable, e.g.

control:any=null;

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
}

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()">

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

or

<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'}]

make some like

<!--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>

And our children becomes

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

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天全站免登陆