Несколько элементов управления формы в дочернем компоненте с помощью средства доступа к значению элемента управления, используя Angular 5 - PullRequest
0 голосов
/ 18 сентября 2018

Я хочу реализовать функциональность с помощью средства доступа к значению элемента управления в Angular 5. Это похоже на доступ к элементу управления несколькими формами в дочернем пользовательском компоненте из родительского элемента.Пожалуйста, дайте мне знать, смогу ли я достичь этого другим способом. Обязательная форма шаблона.

Если есть какие-либо другие общие элементы для создания настраиваемого элемента управления с двухсторонним связыванием данных, пожалуйста, дайте мне знать.Было бы здорово, если бы ответы были на Plunker или StackBlitz.

Вот мой: https://stackblitz.com/edit/angular-qzioet

Родительский компонент: -

export class AppComponent implements OnInit  {
  public countryList: any = [];
  public option: any =[ ];
      public personal = {
   identity: {
  name: {firstname: null, lastname: null },
  age: null,
  sex: null
   }
 }
  @ViewChild('personalForm') form: any;
 constructor() {

   }

Родительский html: -

<app-input name ='name' [(ngModel)]="personal.identity.name" [form]="personalForm" ngDefaultControl></app-input>

Дочерний компонент: -

   import {Component, Input, forwardRef} from '@angular/core'
   import { 
    FormControl,
         FormGroup,
    ControlValueAccessor,
    NG_VALUE_ACCESSOR,
        NG_VALIDATORS,
     Validator
         } from '@angular/forms';


    @Component({
 selector: 'app-input',
   templateUrl: "./input-child.html",
          providers: [
{ 
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => Child),
  multi: true
},
{
  provide: NG_VALIDATORS,
  useExisting: forwardRef(() => Child),
  multi: true,
} 
   ]
   })

   export class Child implements ControlValueAccessor, Validator {
 @Input() form: any;
  @Input() name: any;
 childControl = new FormGroup({ firstname: new FormControl() , 
 lastname: new FormControl() });

 fn: (value: any) => void;
 constructor() {
     console.log(this.childControl);
  }

   writeValue(value: any) {
 if (value) {
  this.childControl.setValue(value);
 }
 }  

  registerOnChange(fn: (value: any) => void) {
   this.fn = fn;
  }

   registerOnTouched() {}

    validate(c: FormControl) {

        return this.childControl.errors;
        };
    }

Дочерний html: -

    `<h1>Child</h1>
    <div>
 <input [formControl]="firstname" (input)="fn($event.target.value)" 
    required>

<input [formControl]="lastname" name="lastname" 
 (input)="fn($event.target.value)" required>

</div>`

1 Ответ

0 голосов
/ 27 мая 2019

То, что вы хотите сделать, может быть достигнуто легче без реализации ControlValueAccessor.Вместо этого вы можете просто установить viewProviders в дочернем компоненте, чтобы использовать существующий родительский NgForm в качестве ControlContainer.

Тогда нет необходимости передавать форму в качестве входного параметра дочернему компоненту, так как элементы управления формой будутавтоматически становится частью родительской формы.

input-child.component.ts:

@Component({
    selector: 'input-child',
    templateUrl: './input-child.component.html',
    viewProviders: [{ provide: ControlContainer, useExisting: NgForm}]
})
export class Child {
    @Input() personalName = {};

    ...
}

input-child.component.html:

<h1>Child</h1>
<div>
    <input [(ngModel)]="personalName.firstname" name="firstname" required>
    <input [(ngModel)]="personalName.lastname" name="lastname" required>
</div>

parent.component.ts:

export class AppComponent {
    public countryList: any = [];
    public option: any =[ ];
    public personal = {
        identity: {
            name: {firstname: 'first-name', lastname: 'last-name' },
            age: null,
            sex: null
        }
    }

    ...
}

parent.component.html:

<form #personalForm="ngForm" name="personalForm">
    <child-input [personalName]="personal.identity.name"></child-input>
</form>
...