@ViewChild 总是返回 undefined

Posted

技术标签:

【中文标题】@ViewChild 总是返回 undefined【英文标题】:@ViewChild always returns undefined 【发布时间】:2017-03-18 14:05:23 【问题描述】:

我知道以前有人问过这个问题,但没有一个选择的答案对我有用。

我正在尝试使用 @ViewChild 从 dom 获取我的 ng-select。而且它总是返回 undefined。

这是main.html中的选择:

<ng-select id = "user-select" 
     #userSelect 
     [allowClear]="true"
     [items]="singleSignOnUsers"
     [disabled]="disabled"
     placeholder="No user selected">
</ng-select>

这是我的组件

import  Component, AfterViewInit, ViewChild   from '@angular/core';

@Component(
    moduleId: module.id,
    selector: 'app-main',
    templateUrl: '../app/main.html',
    providers: [ApiHttpService, UserAdministrationService]
)

export class AppComponent 
    @ViewChild('userSelect') userSelect;


    ngAfterViewInit() 
        alert(this.userSelect);
    

我在这里错过了什么?

更新:哦,我的灵魂! 我明白了为什么这在应该的时候不起作用。

我将整个视图包裹在 divngSwitch 中。如果我将其移出,我可以访问它们。

现在我不知道如何在ngSwitch 中访问它们。但我不必使用ngSwitch

<div [ngSwitch]='loading'>
        <div *ngSwitchCase="false">
            ...
            <ng-select id="user-select"
                       #userSelect
                       [allowClear]="true"
                       [items]="singleSignOnUsers"
                       [disabled]="disabled"
                       placeholder="No city selected">
            </ng-select>
            ...
        </div>
    <div

【问题讨论】:

这应该可以。你能在 Plunker 中复制吗? 我从未使用过 plunker。我会看看我能不能弄明白。 Plunker 在[ New | v ] 按钮下提供了一个现成的Angular2 TS 模板。 ng-select 真的出现了吗?组件是否在模块中注册? 是的,ng-select 确实出现了。仅使用 div 或常规选择而不是 ng-select 时,我也会遇到同样的问题 【参考方案1】:

就我而言,我遇到了同样的问题。我console.log()-ed 从子组件中检索到的内容,它给了我“未定义”。

我只是通过刷新页面来解决它。 ctrl+shift+R 可能会有所帮助。我猜是因为浏览器的缓存导致了这个问题。

【讨论】:

【参考方案2】:

我替换了所有出现的

*ngIf="flag"

[style.display]="flag ? 'block' : 'none'"

在我的情况下让它始终如一地工作。否则,我的视图首次加载时不存在的 ViewChild 组件可能永远保持未定义状态。

【讨论】:

不幸的是,这不适用于模型绑定,我认为您的解决方案会通过[hidden]="!flag"得到改进【参考方案3】:

@twaldron 你是否在 ngOnInit 中使用了一些延迟的数据加载?

因为在这种情况下,根据我的经验,将 @ViewChild 作为 ElementRef 读取不会产生任何结果

如果您的组件已经解析了数据(例如父级将子数据对象传递给子组件的情况),它应该可以工作(至少对我来说是这样)。

在异步数据加载的情况下,我能够使其工作的方式是使用更改通知

 @ViewChildren('userSelect') userSelect: QueryList<ElementRef>;

 ngAfterViewInit(): void 
    this.userSelect.changes.subscribe(item => 
        if (this.userSelect.length) 
            alert(this.userSelect.first.nativeElment.outerHTML)
        
    )
 

【讨论】:

我相信这很有意义。我将它包裹在 ngSwitch 中,它在异步获取数据时显示加载 gif。当数据加载完成后,它会被切换并显示元素。最终,我会将 select 的 items 属性设置为加载的数据,这就是我首先尝试访问它的原因。 这对我也有用ngAfterViewInitngOnInit。谢谢。

以上是关于@ViewChild 总是返回 undefined的主要内容,如果未能解决你的问题,请参考以下文章

Angular Viewchild undefined

为啥函数返回的值总是 null 或 undefined?

使用 axios 和 Redux Saga 调用 API 总是返回 undefined

Console.log 总是在 Chrome 中返回 undefined [重复]

使用 node-postgres 查询的 Promise 总是返回 undefined

解析云代码 request.object.get(key) 总是返回 undefined