@ViewChild返回undefined

时间:2018-01-18 12:37:10

标签: angular viewchild

出于某种原因,我的Angular 5 App中的@ViewChild不起作用。 我在我的组件中定义了这个:

区分detail.component.html:

<div class="inner-tab-content" #innerTabContent>
    <!-- // more content here -->
</div>

我在我的控制器中(在构造函数之上)实现了@ViewChild,如下所示:

区分detail.component.ts

@ViewChild('innerTabContent') tabContentElement: ElementRef;

我想在组件中访问它: 的区分detail.component.ts

ngAfterViewInit() {
    console.log("scroll top: " + this.tabContentElement.nativeElement);
}

我已经实现了AfterViewInit接口。正确调用ngAfterViewInit()。但是,this.tabContentElement始终为undefined

非常感谢任何帮助:)

4 个答案:

答案 0 :(得分:9)

ViewChild()可以使用您描述的方案在最新的plunker Angular版本上正常工作。

此弹射器演示:https://plnkr.co/edit/KzWnkE5Hvp7NUow6YAxy

组件:

ngAfterViewInit() {
    console.log(this.testView); // correctly outputs the element in console, not undefined
}
  • 检查&#39; @ angular / core&#39;

  • 是否正确导入了ElementRef和ViewChild
  • 您的元素可能在AfterViewInit时根本不存在(例如,如果有*ngIf(根据您的评论,似乎就是这种情况)< / p>

在后一种情况下,您可以使用包装元素和ViewChildren,在添加新的子元素时会发出一些事件 - 有关此处文档的更多信息:https://angular.io/api/core/ViewChildren

请注意,根据此问题可能存在本地div的问题:@ViewChildren does not get updated with dynamically added DOM elements,但这可以通过使用包装div的新组件来解决。

修改

或者您也可以使用超时来等待呈现组件。我必须说我发现这个解决方案很脏,但很高兴它适合你:)

答案 1 :(得分:6)

但是,即使您访问AfterViewInit中的子组件,有时@ViewChild仍会返回null。问题可能由*ngIf或其他指令引起。

解决方案是使用@ViewChildren而不是@ViewChild并订阅组件准备就绪时执行的changes订阅。

例如,如果您要在父组件ParentComponent中访问子组件MyComponent

import { Component, ViewChildren, AfterViewInit, QueryList } from '@angular/core';
import { MyComponent } from './mycomponent.component';

export class ParentComponent implements AfterViewInit
{
  //other code emitted for clarity

  @ViewChildren(MyComponent) childrenComponent: QueryList<MyComponent>;

  public ngAfterViewInit(): void
  {
    this.childrenComponent.changes.subscribe((comps: QueryList<MyComponent>) =>
    {
      // Now you can access to the child component
    });
  }
}

答案 2 :(得分:1)

有时会对此问题做出不同的回答:访问子组件时,子组件仍未呈现。对我而言,这是由于* ngIf所致,因此子组件仍然不存在。例如,

<div *ngIf="check">
   <app-child-item></app-child-item>
</div>

在您的父.ts文件中,当check设置为false时,您尝试访问childItem。

答案 3 :(得分:1)

为了使它在我的情况下始终有效,我替换了所有出现的

*ngIf="check"

使用

[style.display]="check ? 'block' : 'none'"

否则,当我第一次加载视图时不存在的ViewChild组件可能会保持不确定状态。