Angular 8:组件内部的formControlName下面有多个嵌套级别

Posted

技术标签:

【中文标题】Angular 8:组件内部的formControlName下面有多个嵌套级别【英文标题】:Angular 8: formControlName inside component multiple nested levels below 【发布时间】: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;'做建议的做法是好习惯吗?还是更不推荐的做法?再次感谢 【参考方案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

希望这会有所帮助!

干杯!

【讨论】:

是的,我一直都知道多个输入/输出和服务,只是想知道是否有替代方案,谢谢

以上是关于Angular 8:组件内部的formControlName下面有多个嵌套级别的主要内容,如果未能解决你的问题,请参考以下文章

Angular2:如何在组件内部显示组件标签的内部 HTML?

Angular:使用 NgIf 删除组件、内部表单和元素?

Angular 5:从组件访问元素内部 html 以获取动态生成的元素

如何在Angular的自定义控件组件中触摸内部控件?

Angular 10 在另一个内部使用一个组件(错误:不是已知元素)

如何将带参数的函数传递给Angular中的内部组件