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 层 更明确,即这些嵌套组件是什么,你的形式是什么?您可以制作传递整个表单组值(或映射值)的组件 其实你没有必要使用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
中,我创建了formControl
的age
属性并绑定它。
将age
的值从comp3
更改为将反映在父组件中,即appComponent
希望这会有所帮助!
干杯!
【讨论】:
是的,我一直都知道多个输入/输出和服务,只是想知道是否有替代方案,谢谢以上是关于Angular 8:组件内部的formControlName下面有多个嵌套级别的主要内容,如果未能解决你的问题,请参考以下文章
Angular2:如何在组件内部显示组件标签的内部 HTML?
Angular 5:从组件访问元素内部 html 以获取动态生成的元素