【问题标题】:How to access child component from parent component in Angular?如何从 Angular 中的父组件访问子组件?
【发布时间】:2021-01-05 17:41:10
【问题描述】:

我在子组件中有mat-paginator,如下所示:


child.component.html

<mat-paginator #paginator></mat-paginator>

我想使用@ViewChild()从父组件获取这个分页器,如下所示:


parent.component.html

<child 
    <!-- code omitted for simplicity -->
>
</child>

***parent.component.ts***
@ViewChild('paginator') paginator: MatPaginator;

resetPaginator() {          
    this.paginator.firstPage();
}

但由于 this.paginator 未定义,我无法访问子组件中的分页器。我不确定如何从父级访问分页器。一种方法可能是使用以下方法,但如果有一种优雅的方法,我会更喜欢它。有什么想法吗?

@ViewChild(ChildComponent) child: ChildComponent;

【问题讨论】:

  • 你应该在 AfterViewInit() 生命周期钩子上检查它
  • 但我已经尝试在AfterViewInit() 之后调用的重置方法上使用它。所以,我只需要使用@ViewChild(ChildComponent) child: ChildComponent; 访问子组件中的分页器的优雅方式吗?如果没有,我想我应该使用@ViewChild(ChildComponent) child: ChildComponent; 来访问分页器并设置它的值。有什么想法吗?
  • 从父组件,您可以使用@ViewChild 访问子组件,然后您可以访问分页器

标签: javascript angular angular-material mat-table mat-pagination


【解决方案1】:

Friedrick,parent 只能访问“child”(但如果可以访问 child,则可以访问 child 的所有属性和功能)。所以在你的孩子中你声明

//in CHILD, so this variable can be access from parent
@ViewChild('paginator') paginator: MatPaginator;

在父母中你有一个

@ViewChild('child') child: ChildComponent;

然后你像往常一样得到“孩子的分页器”

this.child.paginator.firstPage();

注意,你也可以给孩子添加一个模板引用,避免声明viewChild

<child-component #child..></child-component>
<button (click)="child.paginatorfirstPage()">first</button>
<button (click)="doSomething(child)">something</button>
doSomething(child:any)
{
    child.paginator.lastPage()
}

【讨论】:

  • 完美!非常感谢。
  • 我也有类似的问题。我有一个mat-tab,首先打开标签容器,然后打开标签。但是,我首先在加载容器时传递参数,然后这些路由参数会通过选项卡丢失。那么,我怎样才能保留这些值并在选项卡中使用它们呢?由于数据首先到达作为父容器的容器,我认为我不能使用@ViewChild 方法。那么,我应该在其中使用什么?
【解决方案2】:

静态查询迁移指南 ​图书馆作者的重要提示:此迁移对于图书馆作者来说尤其重要,以方便他们的用户在版本 9 可用时升级。

在版本 9 中,@ViewChild 和 @ContentChild 查询的默认设置正在更改,以修复查询中的错误和令人惊讶的行为(在此处阅读更多信息)。

为准备此更改,在版本 8 中,我们正在迁移所有应用程序和库,以明确指定 @ViewChild 和 @ContentChild 查询的解析策略。

具体来说,此迁移添加了一个明确的“静态”标志,指示何时应分配该查询的结果。添加此标志将确保您的代码在升级到版本 9 时以相同的方式工作。

之前:

// query results sometimes available in `ngOnInit`, sometimes in `ngAfterViewInit` (based on template)
@ViewChild('foo') foo: ElementRef;

之后:

// query results available in ngOnInit
@ViewChild('foo', {static: true}) foo: ElementRef;

// query results available in ngAfterViewInit
@ViewChild('foo', {static: false}) foo: ElementRef;

从版本 9 开始,静态标志将默认为 false。届时,任何 {static: false} 标志都可以安全移除,我们将提供一个示意图,为您更新代码。

注意:此标志仅适用于 @ViewChild 和 @ContentChild 查询,因为 @ViewChildren 和 @ContentChildren 查询没有静态和动态的概念(它们总是被解析为“动态”)。

Static query migration guide

【讨论】:

  • 我使用 Angular 10+ 版本。那么,我应该使用哪个标志?为什么?
  • 如果您的子视图是动态的,它的默认值,只需在 ngAfterViewInit 中访问它
  • 如果您的视图子是静态的,请将 static 设置为 true 并在您想要的任何地方使用它
猜你喜欢
  • 1970-01-01
  • 2020-07-10
  • 2023-03-27
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 2019-12-11
相关资源
最近更新 更多