【问题标题】:Cannot read property 'native-element' of undefined无法读取未定义的属性“本机元素”
【发布时间】:2017-09-09 01:33:29
【问题描述】:

我正在使用离子 2。

我需要获取 HTML 元素值。

其实我用的是viewchild。

这是我的html模板代码

<div class="messagesholder" *ngFor="let chat of chatval | orderby:'[date]'; let last = last">
       {{last ? callFunction() : ''}} 

   <div *ngIf="chat.sender == currentuser || chat.receiver == currentuser">    
     <p class="chat-date"  id="abc" #abc>{{chat.date | amDateFormat:'LL'}}</p>                 
              {{checkdate()}}                         
   </div>

chat.date 值是 firebase 值。我访问这个元素。但是我没有得到元素的值。

这是我的组件

import {Component, ElementRef,ViewChild, OnInit} from '@angular/core';

    export class ChatPage   {
      @ViewChild(Content) content: Content;
      @ViewChild('abc')abc: ElementRef;
       constructor(){}

      ngAfterViewInit(){

       console.log("afterinit");
       console.log(this.abc.nativeElement.value);

      }
    }

我参考了这个链接How can I select an element in a component template?

我尝试了很多方法。

但是我收到了这个错误

Cannot read property 'nativeElement' of undefined.

【问题讨论】:

  • 您的&lt;p&gt;*ngIf 中吗?你能在 Plunker 中重现吗?根据您的问题,它应该可以正常工作。 value 应该返回什么? &lt;p&gt; 元素没有 value 属性。
  • 谢谢。我需要原生元素的访问值
  • 你没有回答我的任何问题,原生元素没有价值。
  • 其实我只是控制台this.abc.nativeElement。我得到这个错误无法读取未定义的属性'nativeElement'。为什么?
  • @Günter Zöchbauer

    没有 *ngIf。我控制台 this.abc 的值它在 innerhtml 等....但同时我控制台 this.abc.nativeelement。我无法访问

标签: angular typescript ionic2


【解决方案1】:

不要指定变量 abc 的类型。应该是这样的:

 @ViewChild('abc') abc;

【讨论】:

  • 不幸的是,这种情况下的类型在运行时根本没有改变任何东西。
【解决方案2】:

我认为您正在尝试在完全渲染之前从 html 中获取值。如果您尝试在按钮单击中打印值,它将起作用。

取决于你的代码我已经修改了一点。试试下面,它对我有用。

  ngAfterViewInit() {
    console.log("afterinit");
    setTimeout(() => {
      console.log(this.abc.nativeElement.innerText);
    }, 1000);
  }

注意:如果不起作用,请增加超时时间,然后重试。

【讨论】:

  • @sabari。非常感谢。它的工作。但我有一个疑问。请检查我的代码。我正在更新我的代码。{{chat.date}} 值使用 ngfor。我需要更改 chat.date 的值。
  • 我会尽力帮助你的。但我不明白,你想做什么。你能解释一下吗?
  • 这不是一个好的解决方案,因为问题在于 *ngIf 语句和组件生命周期。如果画布在 DOM 中,ngAfterViewInit 应该能够分配元素 ref,但同样,设置超时是一种 hack,完全无法测试,而且是一种可怕的做法。
  • 您好,我尝试在角度 9 中增加超时时间,但错误仍然存​​在
【解决方案3】:

我认为您应该将代码从 ngAfterViewInit 移动到 ngOnInit 以避免此类问题并且不依赖于超时:

ngOnInit(){
  console.log("afterinit");
  console.log(this.abc.nativeElement.value);   
}

【讨论】:

  • 在移入 ngOnInit() 后也得到相同的异常。
【解决方案4】:

在父组件 html 模板中声明子组件的选择器。否则,组件对象 abc 将不会在运行时初始化以在 parent.ts 文件中调用其函数或公共属性。

子组件 abc:

@Component({
    selector: 'child-abc',
    templateUrl: './abc.component.html',
    styleUrls: ['./abc.component.css'],
})

在父组件的html模板中声明子组件的选择器:

< child-abc > < /child-abc >

【讨论】:

    【解决方案5】:

    最好使用的生命周期挂钩是 AfterContentInit,允许脚本找到所有 html 内容(例如 #map_canvas div)。

    import { AfterContentInit, ViewChild } from '@angular/core';
    

    另外,对 ViewChild 进行了一些更新,现在它需要第二个参数:

    @ViewChild('map_canvas', {static: false}) map_canvas: ElementRef;
    

    现在您可以使用该挂钩来初始化您的地图:

    ngAfterContentInit() {
        this.loadMap();
    }
    

    【讨论】:

    • 这不适用于 Angular 7 及更低版本。由于 Angular 7 中的 @ViewChild 不接受 {static: false} 作为第二个参数。仅适用于 Angular 8。
    • 使用ngAfterContentInit()后仍然出现同样的错误。
    • 仍然会得到与 ngAfterViewInit() 中相同的错误。这仅适用于接受答案所建议的计时器。
    【解决方案6】:

    如果您执行以下操作,则可以将 ElementRef 与 @ViewChild 结合使用

    HTML 标记

    <input type="text" class="form-control" #someNameInput>
    <button
      class="btn btn-primary"
      (click)="clickMe()">Click Me</button>
    

    在组件代码中:

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

    对于旧版本是

    @ViewChild('someNameInput') someNameInput: ElementRef;
    

    就在constructor()方法之前

    下面是在函数中使用它的方法

    clickMe(){
    console.log(this.someNameInput.nativeElement.value);
    

    }

    如果你得到一些值是未定义的,这通常意味着这是一个 JavaScript 问题并且你没有初始化一些东西。首先尝试将 ViewChild 排除在外,并确保代码在没有它的情况下正常工作。然后将 ViewChild 引入组合中。有点像先用邮递员测试你的 API,然后再做 Angular 代码。确保后端首先工作,然后您确定它是 Angular 代码。 Angular 具有不同的页面生命周期,因此某些值仅在 onAfterViewInit 事件中可用,而在其他事件中不可用。所以你必须玩弄视图周期。没试过,但我怀疑如果你尝试在 ngOnInit 方法中获取 ViewChild 的值,你会得到一个错误或空白值。

    【讨论】:

      【解决方案7】:

      对于那些想知道的人请注意,在较新的 Angular (8+) 中使用 ViewChild 时,如果您在使用静态标志时尝试在动态渲染的对象上使用 ViewChild,则可能会收到此错误。

      示例: @ViewChild('someSection',{ static: false }) someSection: ElementRef;

      引入了 { static: true } 选项以支持动态创建嵌入式视图。当您动态创建视图并想要访问 TemplateRef 时,您将无法在 ngAfterViewInit 中这样做,因为它会导致 ExpressionHasChangedAfterChecked 错误。将静态标志设置为 true 将在 ngOnInit 中创建您的视图。

      感谢 Poul Krujit 指出这一点:How should I use the new static option for @ViewChild in Angular 8?

      【讨论】:

        【解决方案8】:

        改为使用一个类来显示/隐藏你被隐藏的元素。

        <div [class.show]="boolean">...</div>
        

        @viewChild not working - cannot read property nativeElement of undefined

        【讨论】:

          猜你喜欢
          • 2019-11-12
          • 1970-01-01
          • 1970-01-01
          • 2023-01-11
          • 2021-03-29
          • 1970-01-01
          • 2018-11-18
          • 2020-04-06
          • 1970-01-01
          相关资源
          最近更新 更多