【问题标题】:Angular 8: formControlName inside component multiple nested levels belowAngular 8:组件内部的formControlName下面有多个嵌套级别
【发布时间】:2020-03-01 14:26:41
【问题描述】:

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

Angular 2 - formControlName inside component

假设实际的 formGroup 位于子 formControlName 组件之上 3 个组件级别,

如果父组件就在子组件旁边,则 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 .. />

【问题讨论】:

  • 问题不清楚 - 你能否让 比孩子高 3 层 更明确,即这些嵌套组件是什么,你的形式是什么?您可以制作传递整个表单组值(或映射值)的组件
  • 位于 Dom 树中 formControlName 上方的 3 个组件
  • 其实你没有必要使用formControlName,你可以简单地使用formControl.get('path.to.prop')作为控件。
  • 嗨@Sergey你能写个例子吗,我可以发积分吗?顺便说一句,我有 Angular 8;'做建议的做法是好习惯吗?还是更不推荐的做法?再次感谢

标签: javascript html css angular angular8


【解决方案1】:

您可以考虑四个选项:

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

d.component.ts

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

Ng-run Example

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 Example

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 Example

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

d.component.ts

export class DComponent implements OnInit {
  control: FormControl;

  constructor(private formService: FormService) { }

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

Ng-run Example

4) 将 FormGroup 作为 Input props 传递给子级或通过 DI 或服务获取,然后使用 formGroup 指令包装您的 input[formControlName]

d.component.html

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

Ng-run Example

【讨论】:

    【解决方案2】:

    Stackblitz

    我想这就是你要找的东西

    按照 stackblitz 示例进行操作

    我已经创建了 3 个组件 comp1 comp2 comp3

    我在appModule 中创建了注册表单并将formGroup 传递给comp1 => comp2 => comp3

    comp3 中,我创建了formControlage 属性并绑定它。 将age 的值从comp3 更改为将反映在父组件中,即appComponent

    希望这会有所帮助!

    干杯!

    【讨论】:

    • 是的,我一直都知道多个输入/输出和服务,只是想知道是否有替代方案,谢谢
    猜你喜欢
    • 2020-03-01
    • 2017-04-24
    • 2018-05-25
    • 2017-02-01
    • 2020-09-17
    • 1970-01-01
    • 2018-03-03
    • 2017-08-12
    • 1970-01-01
    相关资源
    最近更新 更多