Angular 8:formControlName 组件内的多个嵌套级别

7 html javascript css angular angular8

使用此资源,我想在多个嵌套级别上实现 formControlName。

Angular 2 - 组件内的 formControlName

假设实际的 formGroup 比子 formControlName 组件高 3 个组件级别,

如果父组件紧挨着子组件,则 ControlValueAccessor 起作用。然而,以上(祖父)形式的多个级别不起作用。

是否有服务或多个输入/输出的替代方案?或者这些是唯一的方法?

A--> Component with formGroup 
   B---> Component container
      C---> Component container
        D ---> Component with FormControlName (should pass to Component A)
Run Code Online (Sandbox Code Playgroud)

组件A会从类似的不同子组件中收集多个表单控件名称,

输入文本.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}
}
Run Code Online (Sandbox Code Playgroud)

输入文本.html

 <input .. />
Run Code Online (Sandbox Code Playgroud)

yur*_*zui 9

您可以考虑四个选项:

1) 使用 FormControlName 在您的组件上提供 ControlContainer

d.component.ts

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

吴运行示例

2) 创建提供 ControlContainer 的简单指令

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

然后将此指令放在节点层次结构顶部的某个位置

d.component.html

<ng-container provideContainer>
  <input formControlName="someName">
</ng-container>
Run Code Online (Sandbox Code Playgroud)

吴运行示例

3) 使用 FormControlDirective 而不是 FormControlName 指令

FormControlDirective需要传递FormControl实例

<input [formControl]="control">
Run Code Online (Sandbox Code Playgroud)

您可以通过 DI 获取此实例:

d.component.ts

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

  ngOnInit() {
    this.control = this.parentFormGroupDir.control.get('someName');
  }
Run Code Online (Sandbox Code Playgroud)

吴运行示例

或者使用一些服务来绑定你的组件。

d.component.ts

export class DComponent implements OnInit {
  control: FormControl;

  constructor(private formService: FormService) { }

  ngOnInit() {
    this.control = this.formService.get('someName');
  }
Run Code Online (Sandbox Code Playgroud)

吴运行示例

4) 将 FormGroup 作为 Input props 传递给孩子或通过 DI 或 service 获取它,然后用 formGroup 指令包装 input[formControlName]

d.component.html

<ng-container [formGroup]="formGroup">
 <input formControlName="..."
</ng-container>
Run Code Online (Sandbox Code Playgroud)

吴运行示例