@ViewChild返回undefined

dav*_*688 8 viewchild angular

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

案例detail.component.html:

<div class="inner-tab-content" #innerTabContent>
    <!-- // more content here -->
</div>
Run Code Online (Sandbox Code Playgroud)

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

案例detail.component.ts

@ViewChild('innerTabContent') tabContentElement: ElementRef;
Run Code Online (Sandbox Code Playgroud)

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

ngAfterViewInit() {
    console.log("scroll top: " + this.tabContentElement.nativeElement);
}
Run Code Online (Sandbox Code Playgroud)

我已经实现了AfterViewInit界面.正确调用ngAfterViewInit().但是,this.tabContentElement总是如此undefined.

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

Pac*_*ac0 12

ViewChild() 适用于您描述的场景的最新plunker Angular版本.

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

零件 :

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

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

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

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

编辑

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

  • 依赖超时是一个非常糟糕的主意。 (3认同)

Mar*_*ero 7

但是,即使您访问了子组件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
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 但是,如果到达 ngAfterViewInit 时 this.childrenComponent 仍未定义,你会怎么做——没有什么可订阅的:( (2认同)

dil*_*111 6

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

<div *ngIf="check">
   <app-child-item></app-child-item>
</div>
Run Code Online (Sandbox Code Playgroud)

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


Joh*_*ord 6

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

*ngIf="check"
Run Code Online (Sandbox Code Playgroud)

[style.display]="check ? 'block' : 'none'"
Run Code Online (Sandbox Code Playgroud)

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

  • 不适用于动态添加的控件,例如在按钮单击上添加的表格行 (2认同)