Angular 中的 ViewChild 和 ControlValueAccessor 有什么区别?似乎他们都可以访问子组件、指令、DOM。对用法的差异如此好奇,一个人能做另一个人不能做的事吗?
2 回答
ViewChild用于从父组件类访问子组件、指令或 DOM 元素,例如,如果您想访问子元素的本机 DOM 属性,那么您可以使用ViewChild来访问该元素并访问它的元素.nativeElement示例。
ControlValueAccessor充当 Angular 表单 API 和 DOM 中的原生元素之间的桥梁。当您想要创建自定义表单元素并希望该元素成为 Angular 表单 API 的一部分时,您将使用它,以便验证和其他事情起作用。例如,您可能想要创建一个自动完成控件并希望它成为表单组的一部分,然后您将实现ControlValueAccessor,例如。
ControlValueAccesor 用于制作自定义表单控件。
一步一步,FormControl 可以存储任何东西,甚至是一个对象。想象两个不同的 FormGroup
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')
})
两者都具有相同的“价值”
{name:'name',direction:{address:'adress',cp:'cp'}}
使用表单数组时,您可以拥有
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')
})]
})
再一次,两者都给出相同的“价值”
{
name:'name',direction:[
{address:'address1',cp:'cp1'},
{address:'address2',cp:'cp2'}]
}
您可以制作自定义表单控件来控制存储对象的FormControl,并使用ControlValueAccessor,但实际上我更喜欢另一种方法(*);它是一个简单的组件,并将 formGroup 或 formControl 作为输入传递。如果您想维护最简单的东西,请不要使用 formControl 来存储对象。如果我有一个组件应用程序方向,例如
@Input()formGroup
<input [formControl]="formGroup('address')">
<input [formControl]="formGroup('cp')">
您可以用作
<app-direction [formGroup]="myform.get('direcction')"></app-direction>
或者如果你有一个表单数组
<div *ngFor="let group of myForm.get('direction').controls">
<app-direction [formGroup]="group"></app-direction>
</div>
没有 ViewChild,没有 ControlValueAccesor,什么都没有,并且表单是在 main.component 中创建的。
好吧,你的队友正在使用 ControlValueAccesor 来控制一个对象?这只是一个意见,但他正在使应用程序复杂化,真的:“让事情变得简单”,看看其他人如何解决类似的问题,重新发明轮子通常是一个坏主意
(*)在我看来,应该使用自定义表单控件来制作具有“特殊外观”的“特殊控件”