26

出于某种原因,我的 Angular 5 应用程序中的 @ViewChild 不起作用。我在我的组件中这样定义它:

case-detail.component.html:

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

我已经@ViewChild在我的控制器(在构造函数之上)中实现了这样的:

case-detail.component.ts

@ViewChild('innerTabContent') tabContentElement: ElementRef;

我想在组件中访问它: case-detail.component.ts

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

我已经实现了AfterViewInit接口。ngAfterViewInit() 被正确调用。然而,this.tabContentElement总是undefined

任何帮助是极大的赞赏 :)

4

4 回答 4

20

ViewChild()在您描述的场景下,在最新的 plunker Angular 版本上运行良好。

在这个 plunker 中的演示:https://plnkr.co /edit/KzWnkE5Hvp7NUow6YAxy

编辑:这是上述 Plunker 的替代 StackBlitz:https ://stackblitz.com/edit/angular-ivy-pzaglm

零件 :

ngAfterViewInit() {
    console.log(this.testView); // correctly outputs the element in console, not undefined
}
  • 检查 ElementRef 和 ViewChild 是否从“@angular/core”正确导入

  • 在 AfterViewInit 时,您的元素可能根本不存在(例如,如果有 a *ngIf(根据您的评论似乎是这种情况)

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

请注意,根据此问题,本机可能存在一些问题div@ViewChildren 不会使用动态添加的 DOM 元素进行更新,但这可以通过使用包装 div 的新组件来解决,例如。

编辑

或者你也可以使用超时来等待组件被渲染。我必须说我发现这个解决方案“脏”,但很高兴它对你有用:)

于 2018-01-18T13:02:19.520 回答
14

但是,即使您访问 中的子组件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
    });
  }
}
于 2018-01-18T13:07:20.243 回答
6

为了让它在我的情况下始终如一地工作,我替换了所有出现的

*ngIf="check"

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

否则,当我的视图首次加载时不存在的 ViewChild 组件可能会保持未定义。

于 2019-11-01T21:24:55.780 回答
4

有时,对这个问题的不同答案是,当您访问子组件时,它仍未呈现。对我来说,这是由于 *ngIf 导致子组件仍然不存在。例如,

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

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

于 2018-10-30T04:18:39.910 回答