@ViewChild returns 未定义
@ViewChild returns undefined
出于某种原因,我的 Angular 5 应用程序中的 @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
。
非常感谢任何帮助:)
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 时根本不存在(例如,如果有 *ngIf
。(似乎是根据您的意见案例)
在后一种情况下,您可以使用包装器元素和 ViewChildren
,它会在添加新子元素时发出一些事件 - 有关文档的更多信息,请参见此处:https://angular.io/api/core/ViewChildren
请注意,根据这个问题:@ViewChildren does not get updated with dynamically added DOM elements,原生 div
可能存在一些问题,但这可以通过使用包装 div 的新组件来解决,例如。
编辑
或者你也可以使用超时来等待组件被渲染。我必须说我找到了这个解决方案 'dirty',但很高兴它对你有用:)
然而,即使您访问 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
});
}
}
这个问题的不同答案有时是,当您访问它时,子组件仍未呈现。对我来说,这是由于 *ngIf,所以子组件仍然不存在。例如,
<div *ngIf="check">
<app-child-item></app-child-item>
</div>
并且在您的父 .ts 文件中,您尝试在检查设置为 false 时访问 childItem。
为了让这个在我的案例中始终如一地工作,我替换了所有出现的
*ngIf="check"
和
[style.display]="check ? 'block' : 'none'"
否则,当我的视图首次加载时不存在的 ViewChild 组件可能会保持未定义状态。
出于某种原因,我的 Angular 5 应用程序中的 @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
。
非常感谢任何帮助:)
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 时根本不存在(例如,如果有
*ngIf
。(似乎是根据您的意见案例)
在后一种情况下,您可以使用包装器元素和 ViewChildren
,它会在添加新子元素时发出一些事件 - 有关文档的更多信息,请参见此处:https://angular.io/api/core/ViewChildren
请注意,根据这个问题:@ViewChildren does not get updated with dynamically added DOM elements,原生 div
可能存在一些问题,但这可以通过使用包装 div 的新组件来解决,例如。
编辑
或者你也可以使用超时来等待组件被渲染。我必须说我找到了这个解决方案 'dirty',但很高兴它对你有用:)
然而,即使您访问 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
});
}
}
这个问题的不同答案有时是,当您访问它时,子组件仍未呈现。对我来说,这是由于 *ngIf,所以子组件仍然不存在。例如,
<div *ngIf="check">
<app-child-item></app-child-item>
</div>
并且在您的父 .ts 文件中,您尝试在检查设置为 false 时访问 childItem。
为了让这个在我的案例中始终如一地工作,我替换了所有出现的
*ngIf="check"
和
[style.display]="check ? 'block' : 'none'"
否则,当我的视图首次加载时不存在的 ViewChild 组件可能会保持未定义状态。