问题
What's the difference between ViewChild and ControlValueAccessor in Angular? Seems both of them can access child components, directives, DOM. So curious about the differences in usage, can one do something the other cannot do?
回答1:
ControlValueAccesor is for making a custom form control.
By steps, a FormControl can store anything, even an object. Imagine two different FormGroups
form1=new FormGroup({
name:new FormControl('name')
direcction:new FormControl({address:'address',cp:'cp'})
})
form2=new FormGroup({
name:new FormControl('name')
direction:new FormGroup({
address:new FormControl('address'),
cp:new FormControl('cp')
})
both have the same "value"
{name:'name',direction:{address:'adress',cp:'cp'}}
While using a form array, you can have
form1=new FormGroup({
name:new FormControl('name')
direcction:new FormArray([
new FormControl({address:'address1',cp:'cp1'}),
new FormControl({address:'address2',cp:'cp2'})
]
})
form2=new FormGroup({
name:new FormControl('name')
direction:new FormArray([
FormGroup({
address:new FormControl('address1'),
cp:new FormControl('cp1')
}),
FormGroup({
address:new FormControl('address2'),
cp:new FormControl('cp2')
})]
})
And again, both give the same "value"
{
name:'name',direction:[
{address:'address1',cp:'cp1'},
{address:'address2',cp:'cp2'}]
}
You can make a custom form control to control a FormControl that stores an object, and the use ControlValueAccessor, but really I prefer another approach(*); that it's make a simple component and pass as input the formGroup or the formControl. If you want to maintenance the things simplest not use a formControl to store an object. If I have a component app-direction like
@Input()formGroup
<input [formControl]="formGroup('address')">
<input [formControl]="formGroup('cp')">
You can use as
<app-direction [formGroup]="myform.get('direcction')"></app-direction>
or if you have a Form Array
<div *ngFor="let group of myForm.get('direction').controls">
<app-direction [formGroup]="group"></app-direction>
</div>
No ViewChild, no ControlValueAccesor, no nothing, and the form is created in the main.component.
Well, your teammate is using a ControlValueAccesor to control an object? It's only an opinion, but he is complicating the application, really: "makes things simple", see how others resolve similar problems, re-inventing the wheel usually is a bad idea
(*)In my opinion a custom form control should be used to make a "special control" with a "special appearance"
回答2:
ViewChild
is used to to get access to a child component, directive or a DOM element from a parent component class, e.g. if you want to access the native DOM properties of a child element then you may use ViewChild
to get access to the element and access it element.nativeElement example.
ControlValueAccessor
acts as a bridge between the Angular forms API and a native element in the DOM. You will use this when you want to create a custom form element and want that element to be part of Angular forms API, so that the validation and other things work. e.g. You may want to create a auto-complete control and want it to be part of form group, then you will implement ControlValueAccessor
, example.
来源:https://stackoverflow.com/questions/60163266/angular-difference-viewchild-vs-controlvalueaccessor