How to implement Reactive Form as custom component using NG_VALUE_ACCESSOR?

寵の児 提交于 2019-12-11 17:26:57

问题


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?


回答1:


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)



来源:https://stackoverflow.com/questions/56576068/how-to-implement-reactive-form-as-custom-component-using-ng-value-accessor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!