Угловой 8: formControlName внутри компонента несколько вложенных уровней ниже - PullRequest
4 голосов
/ 05 ноября 2019

Используя этот ресурс, я хочу реализовать formControlName для нескольких вложенных уровней.

Angular 2 - formControlName внутри компонента

Скажем, фактическая форма FormGroup живет на 3 уровня вышедочерний компонент formControlName,

ControlValueAccessor работает, если родительский компонент находится рядом с дочерним. Однако несколько уровней выше (дедушка) форма не работает.

Есть ли альтернатива обслуживанию или несколько входов / выходов? Или это единственный метод?

A--> Component with formGroup 
   B---> Component container
      C---> Component container
        D ---> Component with FormControlName (should pass to Component A)

Компонент A будет собирать несколько имен элементов управления формы из разных дочерних компонентов, аналогично этому,

InputText.ts

export class InputTextComponent implements  AfterViewInit, ControlValueAccessor  {
  @Input() disabled: boolean;
  @Output() saveValue = new EventEmitter();

  value: string;
  onChange: () => void;
  onTouched: () => void;

  writeValue(value: any) {
    this.value = value ? value : "";
  }

  registerOnChange(fn: any) {this.onChange = fn}

  registerOnTouched(fn: any) {this.onTouched = fn}

  setDisabledState(isDisabled) {this.disabled = isDisabled}
}

InputText.html

 <input .. />

Ответы [ 2 ]

2 голосов
/ 10 ноября 2019

Можно рассмотреть четыре варианта:

1) предоставить ControlContainer для вашего компонента с FormControlName

d.component.ts

@Component({
  ...
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
})
export class DComponent implements OnInit {

Ng-run Пример

2) создать простую директиву, которая предоставляет ControlContainer

@Directive({
  selector: '[provideContainer]',
  providers: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
})
export class ProvideContainerDirective {
}

затем поместите эту директиву где-нибудь наверху иерархии узлов в вашем

d.component.html

<ng-container provideContainer>
  <input formControlName="someName">
</ng-container>

Ng-run Пример

3) использовать FormControlDirective вместо директивы FormControlName

FormControlDirective требуется FormControl экземпляр, подлежащий передаче

<input [formControl]="control">

Вы можете получить этот экземпляр либо DI:

d.component.ts

export class DComponent implements OnInit {
  control;
  constructor(private parentFormGroupDir: FormGroupDirective) { }

  ngOnInit() {
    this.control = this.parentFormGroupDir.control.get('someName');
  }

Ng-Run Пример

или используйте какой-либо сервис, который связывает ваши компоненты.

d.component.ts

export class DComponent implements OnInit {
  control: FormControl;

  constructor(private formService: FormService) { }

  ngOnInit() {
    this.control = this.formService.get('someName');
  }

NG-Run экзаменple

4) передать FormGroup в качестве Input для поддержки дочерних элементов или получить его через DI или службу, а затем обернуть ваш ввод [formControlName] директивой formGroup

d.component.html

<ng-container [formGroup]="formGroup">
 <input formControlName="..."
</ng-container>

Ng-Run Пример

0 голосов
/ 10 ноября 2019

Stackblitz

я думаю, это то, что вы ищете

следуйте примеру стекаблиц

Я создал 3 компонента comp1 comp2 comp3

Я создал форму регистрации в appModule и передаю formGroup в comp1 => comp2 => comp3

В comp3 я создал formControl из age свойства и связал его. При изменении значения age с comp3 оно будет отражено в родительском компоненте, то есть appComponent

Надеюсь, это поможет!

Cheers!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...