【问题标题】:How to call public method of ViewChild in Angular 10如何在 Angular 10 中调用 ViewChild 的公共方法
【发布时间】:2021-04-12 16:14:59
【问题描述】:

我正在尝试从我的父组件调用子组件的公共方法,但我收到了错误

core.js:5967 ERROR TypeError: this.foo.bar 不是函数

我理解这是因为即使我的 ViewChild 是 ChildComponent 类型,它实际上不是 ChildComponent,它只是与 ChildComponent 相同的形状,但最终只是一个普通的旧 JS 对象。

那么如何在子组件上调用公共方法呢?

我的代码如下:

父.html

<app-child-component #childComponent></app-child-component>

父.ts

export class ParentComponent implements OnInit {
{
    @ViewChild('childComponent') childComponent:ChildComponent;

    ngOnInit(): void {
        this.childComponent.foo(); // ERROR TypeError: this.childComponent.foo is not a function
    }
}

childComponent.ts

export class ChildComponent implements OnInit {
{
    public foo(): void
    {
        // ...
    }
}

【问题讨论】:

  • 你能检查一下父级中childComponent 的实例是什么吗?通过控制台.log
  • 试试 AfterViewInit 而不是 OnInit。
  • 也可以按班级查询@ViewChild(ChildComponent) childComponent: ChildComponent;

标签: angular


【解决方案1】:

在解决问题并得到 lead me to this question 的另一个错误后,我意识到定义子组件的模块中的组件是 declarations,但不是 exports

我有什么:

@NgModule({
    declarations: [
        ChildComponent
    ],
    imports: [
        SharedModule
    ]
})
export class ChildModule {
}

我需要什么:

@NgModule({
    declarations: [
        ChildComponent
    ],
    imports: [
        SharedModule
    ],
    exports: [
        ChildComponent
    ]
})
export class ChildModule {
}

【讨论】:

    【解决方案2】:

    无法调用foo(),因为OnInit 生命周期挂钩触发时childComponent 对象尚未实例化。

    来自 Angular 生命周期钩子documentation

    Hook method Purpose Timing
    ngOnInit() Initialize the directive or component after Angular first displays the data-bound properties and sets the directive or component's input properties. Called once, after the first ngOnChanges().

    相反,您应该在AfterViewInit 回调中调用childComponent.foo()

    Hook method Purpose Timing
    ngAfterViewInit() Respond after Angular initializes the component's views and child views, or the view that contains the directive. Called once after the first ngAfterContentChecked().

    您的解决方案是:

    export class ParentComponent implements AfterViewInit {
    {
        @ViewChild('childComponent') childComponent: ChildComponent;
    
        ngAfterViewInit(): void {
            this.childComponent.foo(); 
        }
    }
    

    【讨论】:

    • 这对我不起作用。如果我在 ngAfterViewInit 中调用该方法,我会得到ERROR TypeError: this.childComponent.foo is not a function。如果我console.log(this.childComponent) 我得到ElementRef {nativeElement: app-child-component.ng-tns-c519-21}。奇怪的是,我发现这个 StackBlitz 正是我正在做的 stackblitz.com/edit/…,同样使用 ViewChild 在元素上同样使用 #foo,正如您在 StackBlitz 中看到的那样,console.log 显示 ChildComponent而不是`ElementRef.
    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    相关资源
    最近更新 更多