![](/img/trans.png)
[英]Angular - ViewChild(Directive) returns undefined in Directive
[英]Angular 8 viewChild returns undefined
我正在尝试访问 childView 实例,但它一直说 childView 未定义。
这是我的 childViews 代码:
@ViewChild(CreateQuestionnaireComponent,{ read: true, static: false }) private childQuestionnaireDialog:CreateQuestionnaireComponent;
@ViewChild(ProjectNavbarComponent,{ read: true, static: false }) private childProjectNavBar:ProjectNavbarComponent;
@ViewChild(QuestionnaireNodeComponent,{ read: true, static: false }) private childQuestionnaireNode:QuestionnaireNodeComponent;
....
onCreateTerminal() {
this.childQuestionnaireDialog.generateQuestionnaireDropDownList();
this.childQuestionnaireDialog.resetFields();
this._hideQuestionnaireDialog = false;
this._modalTitle = 'New Terminal';
this._placeHolderText = 'Terminal Questionnaire Title';
this._terminal = true;
}
...
它说:this.childQuestionnaireDialog 未定义”。
它正在与 Angular 7 一起工作。
根据我的新知识,@viewChild 带有一个名为 static 的标志。如果我们将该标志设置为 true,则父组件会在其自己的创建过程中尝试获取对 childView 的引用。 换句话说,我们可以在父组件的 onInit() 方法中有一个 childView 的实例。基本上是一次性访问,因为我们将无法在任何其他方法中访问。
标志设置为 false,基本上是 ivy 渲染器中的新方法。
我的问题是,这两个选项都不起作用。
我有一个类似的问题,其中 ViewChild 组件在 onInit() 方法中未定义。
// Ensure Change Detection runs before accessing the instance
@ContentChild('foo', { static: false }) foo!: ElementRef;
// If you need to access it in ngOnInit hook
@ViewChild(TemplateRef, { static: true }) foo!: TemplateRef;
您必须在视图完成初始化之前尝试访问 ViewChild 查询的结果。
因此,您可以将查询标记为静态:
@ViewChild('test', {static: true}) test: ElementRef;
...或将逻辑移至 ngAfterViewInit (首选)。
我花了一个小时没有在 SO 上找到它,所以它也可以帮助其他人:我的错误是我在 angular html 中使用了错误的选择器。 我想引用的组件如下所示:
@Component({
selector: 'app-universal-modal',
templateUrl: './universal-modal.component.html',
styleUrls: ['./universal-modal.component.scss']
})
export class UniversalModalComponent implements OnInit {
现在我在其父级中使用了 viewchild:
@ViewChild('universalModalComponent', {static: true}) universalModalComponent: UniversalModalComponent;
并且 html 选择器应该是app-universal-modal :
<app-universal-modal #universalModalComponent ></app-universal-modal>
但是我使用了新任务选择器。
奇怪的是没有编译时错误,而是运行时错误......
就我而言,我让我的孩子处于 *ngIf 状态。 因此 ViewChild 无法初始化所需的元素。 更新了在 *ngIf 之外渲染组件的逻辑,因此 ViewChild 能够成功初始化元素。
因此,如果可能,当需要 ViewChild 时,更改逻辑以在 *ngIf 之外呈现组件并显示适当的消息。 或者使用 CSS 隐藏元素的可见性,而不是使用 *ngIf。
如果您在 .HTML 文件中的*ngIf
条件中使用 #viewchildTemplateRef 元素,则 .ts 文件中的 @ViewChild 选择器/引用变量将是未定义的。 因此,请改用[ngClass]
。
示例:使用[ngClass]={'hide': data.length = 0}
而不是*ngIf=data.length>0
我这边的问题略有不同,因此为后代添加。
我最初是在实现一个@ViewChild
并且在组件的范围内一切正常。
但是,我正在实现一个事件订阅,以在事件中使用this.action()
来this.action()
孩子的方法,该事件通过事件丢失了它的引用。 (我这边的不良事件)
对我来说很奇怪,但一种解决方案(不是最佳解决方案,但在事件管理器重构之前)是在订阅创建时传递对此的引用。
var self = this; // var because we want it to stick around.
subscription.event.subscribe(()=>{
self.callOnThisRef();
})
我确信这是设计使然,因为它突出了我的活动管理问题。 但是调试起来很奇怪。
对于 Angular 7,我们不会得到{static: boolean}
参数,而是得到{read: any}
在我的情况下,我有一个*ngif
指令,所以元素的引用不是通过 Viewchild() 获取的,我所做的我刚刚检查了 Component.ts 中的元素是否未定义
如果你需要在 ngOnInit 钩子中访问它
这是通过热听删除类的示例
@ViewChild('elref', ) elref: ElementRef;
import { Component, ElementRef, , Renderer2, ViewChild } from'@angular/core';
export class Component implements OnInit {
@ViewChild('elref', ) elref: ElementRef;
constructor(private renderer: Renderer2) {}
ngOnInit() { this.hotlistening(); }
hotlistening() {
this.renderer.listen('window', 'click', (e: Event) => {
if (this.elref !== undefined) { //Here i checked for undefined
this.elref.nativeElement.classList.remove('open');
});
}
}
@ViewChild('test', {static: false}) 测试:ElementRef;
我有错误,但造成的更隐蔽。 只是我的视图子组件在模板上有一个错误,其中一个变量未定义。 我只是因为我修改了 HTML 才感觉到它。 一旦没有触发错误消息,就很难注意到错误。
(我知道这个问题有点老了。但对于那些仍然像我一样发现提示的人)
我也遇到过这个问题,我发现当您的元素位于具有*ngIf
的父元素时, {static: true}
选项可能无法始终正常工作。
我的解决方法是将该元素设为子组件并在其自己的 ngOnInit 或 ngAfterViewInit 上使用它。 这样,我就不用去检查它是否真的存在,订阅更改,或者一些复杂的额外工作。
也许你也可以考虑一下。 如果可能,我认为这是最简单的解决方案。
让孩子在ngOnInit()
中可用
@ViewChild(CreateQuestionnaireComponent,{ read: true, static: false }) private childQuestionnaireDialog:CreateQuestionnaireComponent;
让孩子在ngAfterViewInit()
中可用
@ViewChild(CreateQuestionnaireComponent,{ read: true, static: false }) private childQuestionnaireDialog:CreateQuestionnaireComponent;
但请确保您的父组件 html 中的子组件<app-questionnaire> </app-questionnaire>
的选择器不应嵌入任何条件,否则它不会遵循上述模式,它将要求条件先为真。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.