【问题标题】:Angular Difference ViewChild vs ControlValueAccessor角度差异 ViewChild 与 ControlValueAccessor
【发布时间】:2020-05-26 12:44:24
【问题描述】:

Angular 中的 ViewChild 和 ControlValueAccessor 有什么区别?似乎他们都可以访问子组件、指令、DOM。对用法的差异如此好奇,一个人能做另一个人不能做的事吗?

【问题讨论】:

  • 不确定确切的区别,但 ControlValueAccessor 用于表单 API 相关的东西,ViewChild 通常访问任何 DOM 元素
  • ControlValueAccesor 是制作一个自定义表单控件,这是一个“特殊控件”,可以使用 [(ngModel)] 或 FormControl 来控制变量。例如一个仪表,一个 datePiker 等。 ViewChild 是获取组件内部的一个元素。没有任何相似之处
  • 嗨 @Eliseo 随时回答,我可以发送积分,仅作为背景信息,我有队友使用 ControlValueAccessor 访问子 FormBuilder 组件地址(具有多个字段,城市,州,邮编等),问题是是否使用 ViewChild 或 ControlValueaccessor 来访问此表单构建器

标签: angular typescript angular8 viewchild controlvalueaccessor


【解决方案1】:

ControlValueAccesor 用于制作自定义表单控件

按步骤,FormControl 可以存储任何东西,甚至是一个对象。想象两个不同的 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')
   })

两者具有相同的“价值”

{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 来控制一个对象?这只是一个意见,但他正在使应用程序复杂化,真的:“让事情变得简单”,看看其他人如何解决类似的问题,重新发明轮子通常是一个坏主意

(*)我认为应该使用自定义表单控件来制作具有“特殊外观”的“特殊控件”

【讨论】:

【解决方案2】:

ViewChild 用于从父组件类访问子组件、指令或 DOM 元素,例如如果您想访问子元素的原生 DOM 属性,那么您可以使用 ViewChild 来访问该元素并访问它 element.nativeElement example

ControlValueAccessor 充当 Angular 表单 API 和 DOM 中的原生元素之间的桥梁。当您想要创建自定义表单元素并希望该元素成为 Angular 表单 API 的一部分时,您将使用它,以便验证和其他事情起作用。例如您可能想要创建一个自动完成控件并希望它成为表单组的一部分,然后您将实现ControlValueAccessorexample

【讨论】:

  • 我还可以用Viewchild访问子组件变量和子Forms,不仅DOM很有趣
  • 是的,这就是我提到的“访问子组件、指令或 DOM 元素”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多