Angular 8 viewChild返回未定义

时间:2019-06-03 22:07:49

标签: javascript angular web angular8

我正在尝试访问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的引用。换句话说,我们可以在父Component的onInit()方法中拥有childView的实例。基本上是一次访问,因为我们无法使用任何其他方法进行访问。

设置为false的标志基本上是常春藤渲染器中的新方法。

我的问题是,这两个选项都不起作用。

10 个答案:

答案 0 :(得分:1)

根据docs,元数据属性 read 为:

`read - read a different token from the queried elements.`

换句话说,如果您想读入ViewContainerRef或组件名称而不是普通的ElementRef(这是默认设置,则省略read)将使用它。因此,将true用作值表示要从元素返回类型true,据我所知这是不可能的。

更好的解释是here,但是对您的问题的简短回答是删除read属性或指定ElementRef或所需的特定类型。

答案 1 :(得分:1)

在我的情况下,我以* ngIf条件渲染了我的孩子。因此,ViewChild无法初始化所需的元素。更新了在* ngIf外部渲染组件的逻辑,ViewChild在那里能够成功初始化该元素。

因此,如果可能的话,在需要ViewChild时,请更改逻辑以在* ngIf之外呈现组件并显示适当的消息。或使用CSS而不是* ngIf隐藏元素的可见性。

答案 2 :(得分:1)

@ViewChild('test', {static: false}) 测试:ElementRef;

答案 3 :(得分:0)

我有一个类似的问题,其中在onInit()方法中未定义ViewChild组件。

This fixed the issue

// 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;

答案 4 :(得分:0)

在视图完成初始化之前,您必须尝试访问ViewChild查询的结果。

因此,您可以将查询标记为静态:

@ViewChild('test', {static: true}) test: ElementRef;

...或将逻辑移至ngAfterViewInit(首选)。

引用https://angular.io/guide/static-query-migration

答案 5 :(得分:0)

我这边的问题略有不同,因此为后代添加。

我最初是实现@ViewChild,在组件范围内,一切正常。

但是,我正在实施事件订阅,以便在事件发生时使用this.action()在子级上触发方法,该事件通过事件丢失了对它的引用。 (我这边的不良事件)

对我来说很奇怪,但是一种解决方案(不是最佳解决方案,而是在事件管理器重构之前)是在创建订阅时传递对此的引用。

var self = this; // var because we want it to stick around. 

subscription.event.subscribe(()=>{
 self.callOnThisRef();
}) 

我确定这是设计使然,因为它突出了我的事件管理中的问题。但是调试很奇怪。

答案 6 :(得分:0)

对于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');
                });
        }
    }

答案 7 :(得分:0)

我花了一个小时没有在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>

但是我改用了新任务选择器。

奇怪的是,没有编译时错误,但是有一个运行时错误...

答案 8 :(得分:0)

如果您在.HTML文件的list()条件内使用#viewchildTemplateRef元素,则.ts文件中的@ViewChild选择器/引用变量将是未定义的。因此,请改用BuildingRoomLists = [] FusionBuildingName = "Renal Dialysis Unit x6" BuildingList = Building_Data.objects.filter(Building_Name=FusionBuildingName) for b in BuildingList: RoomList = Room_Data.objects.filter(Room_Building=b) RoomList = list(RoomList) BuildingRoomLists += RoomList)

示例:使用*ngIf代替[ngClass]

答案 9 :(得分:0)

我遇到了错误,但导致的原因更隐蔽。只是我的视图子组件在模板上有一个错误,其中一个变量未定义。我只是因为我修改了 HTML 才感觉到它。一旦没有触发错误消息,就很难注意到错误。