34

我正在尝试访问 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 渲染器中的新方式。

就我而言,这两个选项都不起作用。

4

11 回答 11

18

我有一个类似的问题,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;
于 2019-07-01T04:08:22.567 回答
16

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

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

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

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

参考https://angular.io/guide/static-query-migration

于 2019-07-26T09:58:28.567 回答
4

就我而言,我已经让我的孩子处于 *ngIf 条件下。因此 ViewChild 无法初始化所需的元素。更新了在 *ngIf 之外渲染组件的逻辑,ViewChild 能够成功地初始化元素。

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

于 2020-10-08T08:37:48.420 回答
2

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

但相反,我使用了新任务选择器。

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

于 2020-09-06T14:03:07.500 回答
2

如果您*ngIf在 .HTML 文件中的条件内使用 #viewchildTemplateRef 元素,则 .ts 文件中的 @ViewChild 选择器/引用变量将未定义。所以,[ngClass]改用。

示例:使用[ngClass]={'hide': data.length = 0}代替*ngIf=data.length>0

于 2020-12-04T04:16:50.530 回答
1

(我知道这个问题有点老了。但是对于那些仍然像我一样找到提示的人)

我也遇到过这个问题,我发现 {static: true}当您的元素位于具有*ngIf.

对我来说,解决方法是将该元素设为子组件并在其自己的 ngOnInit 或 ngAfterViewInit 上使用它。这样,我就不必检查它是否真的存在,订阅更改,或者一些复杂的额外工作。

也许你也可以考虑一下。如果可能的话,我认为这是最简单的解决方案。

于 2021-08-23T06:26:31.580 回答
1

根据文档,读取的元数据属性是:

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

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

这里有一个更好的解释,但对您的问题的简短回答是取出read属性或指定ElementRef或您想要的特定类型。

于 2019-06-04T03:39:29.410 回答
1

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

于 2021-01-30T08:23:47.590 回答
1

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

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

但是,我正在实现一个事件订阅,以使用 withing 事件在子节点上触发一个方法,this.action()该事件通过事件丢失了它的引用。(我这边的事件很糟糕)

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

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

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

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

于 2020-05-05T22:45:00.693 回答
1

对于Angular 7,我们不会获取参数,{static: boolean}而是获取参数.ts{read: any}*ngif


如果你需要在 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');
                });
        }
    }
于 2020-06-01T10:12:06.773 回答
0

我有错误,但导致的原因更隐蔽。Simply My View Child 组件在模板上出现错误,其中未定义变量。我只是因为我修改了 HTML 才意识到它。一旦没有触发错误消息,就很难注意到错误。

于 2021-04-23T00:48:30.913 回答