调用子组件的方法

Call a method of the child component

我有一个这样的嵌套子组件:

<app-main>
    <child-component />
</app-main>

我的 appMain 组件需要调用子组件的方法。

如何调用子组件的方法?

Parent 和 child 可以通过数据绑定进行通信。

示例:

@Component({
    selector: 'child-component',
    inputs: ['bar'],
    template: `"{{ bar }}" in child, counter  {{ n }}`
})
class ChildComponent{
    constructor () {
        this.n = 0;
    }
    inc () {
        this.n++;
    }
}

@Component({
    selector: 'my-app',
    template: `
        <child-component #f [bar]="bar"></child-component><br>
        <button (click)="f.inc()">call child func</button>
        <button (click)="bar = 'different'">change parent var</button>
    `,
    directives: [ChildComponent]
})
class AppComponent {
    constructor () {
        this.bar = 'parent var';
    }
}

bootstrap(AppComponent);  

Demo

#f 创建对 child 组件的引用,可以在模板中使用或传递给函数。来自 parent 的数据可以通过 [ ] 绑定传递。

您可以使用

获取对元素的引用
@ViewChild('childComponent') child;

其中 childComponent 是模板变量 <some-elem #childComponent>` 或

@ViewChild(ComponentType) child;

其中 ComponentType 是组件或指令的类型,然后在 ngAfterViewInit 或事件处理程序中调用 child.someFunc().

ngAfterViewInit() {
  console.log(this.child);
}

另见

作为子组件

@Component({
    // configuration
    template: `{{data}}`,
    // more configuration
})
export class Son {

  data: number = 3;

  constructor() { }

  updateData(data:number) {
    this.data = data;
  }

}

有父组件

@Component({
    // configuration
})
export class Parent {
  @ViewChild(Son) mySon: Son;

  incrementSonBy5() {
    this.mySon.updateData(this.mySon.data + 5);
  }
}

以父亲为模板

<son></son>
<button (click)="incrementSonBy5()">Increment son by 5</button>

此解决方案仅适用于父模板中的一个 <son></son> 实例。如果您有多个实例,则仅适用于模板的第一个实例。

访问子组件的最佳方式是@ViewChild

假设您的 AppMainComponent 带有示例中的嵌套 ChildComponent。

// app-main.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'app-main',
    template: `
        <child-component />
    `
})

export class AppMainComponent {}

您想从您的 ChildComponent 调用一个清除方法。

// child.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'child-component',
    template: '{{ greeting }}'
})

class ChildComponent {
    greeting: String = 'Hello World!';

    clear() {
        this.greeting = null;
    }
}

您可以通过导入 ChildComponent class、ViewChild 装饰器并将组件的 class 作为查询传递给它来实现。这样,您就可以访问存储在自定义变量中的 ChildComponent 的接口。这是一个例子:

// app-main.component.ts
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './components/child/child.component';

@Component({
    selector: 'app-main',
    template: `
        <child-component />
    `
})

class ChildComponent {
    @ViewChild(ChildComponent)
    child: ChildComponent;

    clearChild() {
        this.child.clear();
    }
}

注意!子视图仅在 ngAfterViewInit.

后可用

Respond after Angular initializes the component's views and child views. Called once after the first ngAfterContentChecked(). A component-only hook.

如果你想自动执行方法,你需要在这个生命周期钩子里面做。

您还可以获得一个 QueryList of child components via ViewChildren 装饰器。

import { Component, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './components/child/child.component';

...

@ViewChildren(ChildComponent)
children: QueryList<ChildComponent>;

QueryList 可能非常有用,例如您可以订阅儿童更改。

也可以创建 template reference variables 并通过 ViewChild 装饰器访问它们。