[英]Acces @ViewChild NgForm refence from child components in parent component
I have following app structure:我有以下应用程序结构:
+--------------------------------------------+
| Parent |
|+------------------------------------------+|
|| Header ||
|| <form #headerForm="ngForm"> ||
|| ... ||
|| </form> ||
|+------------------------------------------+|
|+------------------------------------------+|
|| Content ||
|| <form #contentForm="ngForm"> ||
|| ... ||
|| ||
|| </form> ||
|| ||
|+------------------------------------------+|
+--------------------------------------------+
I would like to reset the states of the forms in the header and content from the Parent component.我想重置 header 中 forms 的状态和Parent组件的内容。 I tried to use @ViewChild/@ViewChildren from the parent component, but I do not know how to access the childs form refs.
我尝试使用父组件中的@ViewChild/@ViewChildren ,但我不知道如何访问子表单引用。
So far I was forced to get a reference of the Header and Content components in the Parent and call a resetForm method:到目前为止,我被迫在Parent中获取Header和Content组件的引用并调用resetForm方法:
export class ParentComponent {
@ViewChildren('componentWithForm') componentsWithForms: QueryList<unknown>;
...
this.componentsWithForms.forEach(component => (component as any).resetFormState());
@Component({
selector: 'app-header',
...
providers: [{ provide: 'componentWithForm', useExisting: forwardRef(() => HeaderComponent) }],
})
export class HeaderComponent {
@ViewChild('headerForm') headerForm: NgForm;
...
resetFormState() {
this.headerForm.reset();
}
Although this technically helps it leads to some ugly TypeScript casting - which I could work around creating a base-class ComponentWithForm , inheriting the Header/Content from it and setting the provider like虽然这在技术上有助于它导致一些丑陋的 TypeScript 铸造 - 我可以解决创建一个基类ComponentWithForm ,从它继承 Header/Content 并将提供者设置为
@Component({
selector: 'app-header',
...
providers: [{ provide: ComponentWithForm, useExisting: forwardRef(() => HeaderComponent) }],
})
export class HeaderComponent extends ComponentWithForm {
but I would actually like to get a direct reference to headerForm/contentForm which would save lot of hassle.但我实际上想获得对 headerForm/contentForm 的直接引用,这样可以省去很多麻烦。
I know that it's not a great change, but If each component with a form you have我知道这不是一个很大的变化,但是如果每个组件都有一个表单
providers:[{provide:'FORM', useExisting:forwardRef(() => YourComponent)}]
and和
@ViewChild(NgForm) form
A directive like像这样的指令
@Directive({
selector: '[haveform]'
})
export class HaveFormDirective implements AfterViewInit {
form:NgForm
constructor(@Host() @Inject('FORM') public component:any, ){ }
ngAfterViewInit()
{
this.form=this.component.form
}
}
Allow you write允许你写
<component haveform></component>
And you can reach the "form" like你可以达到像这样的“形式”
@ViewChildren(HaveFormDirective) forms:QueryList<HaveFormDirective>
this.forms.forEach(x=>console.log(x.form.value)
It think you could use a better solution like @Input()/@Output()
for parent <-> child component communication.它认为您可以使用更好的解决方案,例如
@Input()/@Output()
来进行父 <-> 子组件通信。 But if u want to use @ViewChild
, It will be best to start at official docs:但是如果你想使用
@ViewChild
,最好从官方文档开始:
https://angular.io/guide/lifecycle-hooks#responding-to-view-changes https://angular.io/guide/lifecycle-hooks#responding-to-view-changes
export class AfterViewComponent implements AfterViewChecked, AfterViewInit {
private prevHero = '';
// Query for a VIEW child of type `ChildViewComponent`
@ViewChild(ChildViewComponent) viewChild!: ChildViewComponent;
ngAfterViewInit() {
// viewChild is set after the view has been initialized
this.logIt('AfterViewInit');
this.doSomething();
}
// ...
}
EDITED:编辑:
You can make a base class for all your components with form that contains resetFormState() {}
method implementation:您可以使用包含
resetFormState() {}
方法实现的表单为所有组件创建一个基础 class:
@Directive()
export class YourFormDirective {
resetFormState() { //... }
}
export class HeaderComponent extends YourFormDirective {}
export class ContentComponent extends YourFormDirective {}
And then in parent, query for WithFormDirective
:然后在父级中查询
WithFormDirective
:
@ViewChildren(WithFormDirective) componentsWithForms!: QueryList<WithFormDirective>;
So you can call it without type casting:所以你可以在没有类型转换的情况下调用它:
this.componentsWithForms.forEach(component => component.resetFormState());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.