Угловая разница ViewChild против ControlValueAccessor

В чем разница между ViewChild и ControlValueAccessor в Angular? Кажется, оба они могут получить доступ к дочерним компонентам, директивам, DOM. Так любопытно узнать о различиях в использовании, может ли один сделать то, что не может сделать другой?


person Community    schedule 11.02.2020    source источник
comment
Не уверен в точной разнице, но ControlValueAccessor используется для материалов, связанных с API форм, и ViewChild в целом для доступа к любому элементу DOM   -  person Pardeep Jain    schedule 11.02.2020
comment
ControlValueAccesor предназначен для создания настраиваемого элемента управления формы, специального элемента управления для управления переменной с помощью [(ngModel)] или FormControl. например датчик, datePiker и т. д. ViewChild должен получить элемент внутри компонента. Нет никакого подобия   -  person Eliseo    schedule 11.02.2020
comment
привет @Eliseo, не стесняйтесь размещать в ответе, и я могу отправлять баллы, просто для справочной информации, у меня есть товарищ по команде, использующий ControlValueAccessor для доступа к адресу компонента Child FormBuilder (с несколькими полями, городом, штатом, почтовым индексом и т. д.), вопрос заключался в том, использовать ViewChild или ControlValueaccessor для доступа к этому formbuilder   -  person    schedule 11.02.2020


Ответы (2)


ControlValueAccesor предназначен для создания элемента управления настраиваемой формы.

Пошагово FormControl может хранить что угодно, даже объект. Представьте себе две разные группы форм

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 для управления объектом? Это всего лишь мнение, но на самом деле он усложняет приложение: «упрощает», видит, как другие решают подобные проблемы, изобретать колесо обычно - плохая идея.

(*) На мой взгляд, пользовательский элемент управления формы должен использоваться для создания «особого элемента управления» с «особым внешним видом».

person Eliseo    schedule 11.02.2020
comment
привет @Eliseo, а ты тоже знаешь ответ на этот вопрос? stackoverflow.com/questions/60315005/ - person ; 20.02.2020

ViewChild используется для получения доступа к дочернему компоненту, директиве или элементу DOM из родительского класса компонента, например если вы хотите получить доступ к собственным свойствам DOM дочернего элемента, вы можете использовать ViewChild для получения доступа к элементу и доступа к нему element.nativeElement пример.

ControlValueAccessor действует как мост между API-интерфейсом Angular Forms и собственным элементом DOM. Вы будете использовать это, когда хотите создать настраиваемый элемент формы и хотите, чтобы этот элемент был частью Angular Form API, чтобы проверка и другие вещи работали. например Вы можете создать элемент управления с автозаполнением и сделать его частью группы форм, тогда вы реализуете ControlValueAccessor, пример.

person wolverine    schedule 11.02.2020
comment
Я также могу получить доступ к дочерним переменным компонента и дочерним формам с помощью Viewchild, что очень интересно не только DOM - person ; 11.02.2020
comment
да, это то, что я упомянул, чтобы получить доступ к дочернему компоненту, директиве или элементу DOM - person wolverine; 11.02.2020