gpt4 book ai didi

javascript - 如何在 Angular 中实现表单投影?

转载 作者:行者123 更新时间:2023-12-04 11:52:50 26 4
gpt4 key购买 nike

根据 Kara Erickson 于 2017 年在 Angular Connect 上发表的演讲,我一直在尝试在 Angular 中实现表单投影,但到目前为止还没有成功。
link to talk
不幸的是,唯一可用的代码出现在幻灯片中并且不完整,因此很难解决。
这是我尝试过的,但它抛出错误:https://stackblitz.com/edit/angular-form-projection-3
表单投影的想法是您有一些包装组件,其模板包含 <form>元素并将表单内容投影到其中(谈话中的示例是表单步进器):

<!-- FormStepper -->
<form>
<ng-content></ng-content>
</form>

<!-- containing template, e.g. AppComponent -->
<form-stepper>
<div ngModelGroup="address">
<input name="street" ngModel/>
<input name="city" ngModel/>
</div>
</form-stepper>

像这样的简单实现会导致错误,因为 ngModelGroup 指令期望在表单内,但由于组件边界而无法找到表单指令(ControlContainer 类)。
根据 Kara 的说法,解决方案是从 FormStepperComponent 的提供者中提供 ControlContainer 类。使用 @ViewChild() 装饰器查询,您从组件的 View 中获取表单指令并将其存储在实例属性中,例如 form .
  // within FormStepper
@ViewChild(NgForm) form: NgForm;
然后在 providers 数组中,使用 useFactory 为 ControlContainer 配置一个提供者,这样当它被请求时,它会返回表单实例:
  providers: [
{
provide: ControlContainer,
useFactory: component => {
return component.form;
},
deps: [FormStepperComponent]
}
],

FormStepperComponent 的内容子项中的指令应该能够注入(inject)提供者数组中提供的服务。这应该允许 ngModelGroup 获得对其所需表单的引用。
问题是工厂函数在 View 初始化之前运行,因此此时 component.form 是未定义的。
我还创建了这个演示,它演示了内容投影以及 View 初始化、内容初始化和工厂运行的顺序。
https://stackblitz.com/edit/angular-projection-experiment
您可以在控制台中看到工厂提供程序在 View 初始化之前运行,因此当指令尝试注入(inject)表单时,它只会得到 undefined .
看来本次演讲中的建议是不可能的?

最佳答案

你的工厂没有NgForm的原因查看子定义的是 NgForm ViewChild查询将查询之后 变更检测运行 默认 .您需要更新 NgForm ViewChild查询运行 之前 变化检测运行。这将确保 form属性是在工厂运行时定义的。您可以通过添加属性 static 来做到这一点。查询并将其设置为true,即

@ViewChild(NgForm, { static: true }) form: NgForm;
ViewChild 上的文档更深入地介绍了此选项: https://angular.io/api/core/ViewChild
我相信当这个演讲发表时,Angular 的 ViewChild 会在默认情况下在更改检测运行之前进行查询。此后,Angular 已更新为在默认情况下运行更改检测后进行查询。太糟糕了,他们没有为这次演讲提供代码示例并使用最新的 Angular 进行更新。
我 fork 了你的例子以使其工作: https://stackblitz.com/edit/angular-projection-experiment-uxzdee

关于javascript - 如何在 Angular 中实现表单投影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65008417/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com