如何使用NG_VALUE_ACCESSOR将响应式表单实现为自定义组件?

时间:2019-06-13 08:08:58

标签: angular angular-reactive-forms

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

真的,我不知道你想要什么。您的自定义表单控件也可以与反应式表单一起使用(请参见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()
    }
  )

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

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

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

添加一个变量,例如

control:any=null;

e实现了Validator,将其添加到声明中并创建一个函数来验证我们向“控件”赋值的位置

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中使用类似

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

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

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

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

<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

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

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,例如,是一个自定义表单控件)