Angular2:无法读取未定义的属性“名称”

Posted

技术标签:

【中文标题】Angular2:无法读取未定义的属性“名称”【英文标题】:Angular2: Cannot read property 'name' of undefined 【发布时间】:2017-02-06 21:30:21 【问题描述】:

我开始学习 Angular2。我一直在关注 angular.io 提供的英雄教程。 一切正常,直到我对使用模板的 html 的混乱感到恼火,我使用模板 URL 代替它,并将 HTML 移动到名为 hero.html 的文件中。 生成的错误是“无法读取未定义的属性‘名称’”。 奇怪的是,可以访问指向对象数组的 heros 变量,这样 ngFor 就会根据数组中对象的数量生成正确数量的“li”标签。但是,无法访问数组对象的数据。 此外,即使是包含一些文本的简单变量,也不会在 HTML 中使用 括号显示(请参阅提供的代码)。

app.component.ts

import  Component  from '@angular/core';
@Component(
  selector: 'my-app',
  templateUrl: './hero.html',
  styleUrls:['./styles.css']
)

export class AppComponent 
  title = 'Tour of Heroes';
  heroes = HEROES;
  selectedHero:Hero;

  onSelect(hero: Hero):void
      this.selectedHero = hero;
  


export class Hero
   id: number;
   name: string;


const HEROES: Hero[] = [
    id: 1, name: 'Mr. Nice' ,
    id: 2, name: 'Narco' ,
    id: 3, name: 'Bombasto' ,
    id: 4, name: 'Celeritas' ,
    id: 5, name: 'Magneta' ,
    id: 6, name: 'RubberMan' ,
    id: 7, name: 'Dynama' ,
    id: 8, name: 'Dr IQ' ,
    id: 9, name: 'Magma' ,
    id: 10, name: 'Tornado' 
];

hero.html

<h1>title</h1>
<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes">
    <span class="badge">hero.id</span> hero.name
  </li>
</ul>
<h2>hero.name details!</h2>
<div>
    <label>id: </label>hero.id
</div>
<div>
    <label>name: </label>
    <input [(ngModel)]="selectedHero.name" placeholder="name">
<div>

这是一张照片:

【问题讨论】:

【参考方案1】:

在 Angular 中,有支持 elvis 运算符 ?. 来防止视图渲染失败。他们称其为安全导航运算符。举个例子:

The current person name is nullObject?.name

由于它试图访问 null 值的 name 属性,整个视图消失了,您可以在浏览器控制台中看到错误。它适用于长属性路径,例如a?.b?.c?.d。因此,我建议您每次需要访问模板中的属性时都使用它。

【讨论】:

【参考方案2】:

变量selectedHero 在模板中是null,因此您不能按原样绑定selectedHero.name。对于这种情况,您需要使用elvis operator ?.

<input [ngModel]="selectedHero?.name" (ngModelChange)="selectedHero.name = $event" />

还需要将[(ngModel)] 分为[ngModel](ngModelChange),因为您不能分配给使用elvis 运算符的表达式。

我也认为你的意思是使用:

<h2>selectedHero?.name details!</h2>

代替:

<h2>hero.name details!</h2>

【讨论】:

谢谢。您已经大致确定了问题所在。但是,我仍然遇到问题。我将 hero.name 更改为 selectedHero.name 但仍然遇到相同的错误。我还按照您的指示更新了输入,但错误仍然存​​在。当 标记行被注释掉除了

selectedHero.name 详细信息之外的所有内容!

工作正常。因此我知道 selectedHero 对象的使用不正确。
抱歉,我忘记了代码中的 elvis 运算符。我编辑了答案。应该是:selectedHero?.name 太棒了!我刚刚添加了?,我的代码运行良好。 谢谢,在我的属性修复我的条件数据绑定问题后添加?(如果属性存在)。您能否详细说明because you can't assign to an expression that uses the elvis operator. 的意思? @TetraDev 您的示例之所以有效,是因为它只是一个数据绑定 [] 指令,而不是事件绑定 ()。如果 angular 能够解析语句并识别这些情况,那就太好了,但目前还没有。见github.com/angular/angular/issues/7697【参考方案3】:

为了避免这种情况,您也可以将组件的 selectedHero 成员初始化为一个空对象(而不是让它未定义)。

在您的示例代码中,这将给出如下内容:

export class AppComponent 
  title = 'Tour of Heroes';
  heroes = HEROES;
  selectedHero:Hero = new Hero();

  onSelect(hero: Hero):void
      this.selectedHero = hero;
  

【讨论】:

【参考方案4】:

这对我有用:

export class Hero
   id: number;
   name: string;

   public Hero(i: number, n: string)
     this.id = 0;
     this.name = '';
   
 

并确保你初始化以及 selectedHero

selectedHero: Hero = new Hero();

【讨论】:

【参考方案5】:

您收到此错误是因为您按照英雄教程中写得不好的说明进行操作。我遇到了同样的事情。

具体来说,在标题在模板中显示英雄名称下,它声明:

要在无序列表中显示英雄名称,请插入以下内容 标题下方和英雄详细信息上方的 HTML 块。

后跟此代码块:

<h2>My Heroes</h2>
<ul class="heroes">
  <li>
    <!-- each hero goes here -->
  </li>
</ul>

它不会指示您替换以前的详细代码,它应该。这就是我们剩下的原因:

<h2>hero.name details!</h2>

在我们的*ngFor 之外。

但是,如果您进一步向下滚动页面,您会遇到以下情况:

显示英雄的模板应该是这样的:

<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes">
    <span class="badge">hero.id</span> hero.name
  </li>
</ul>

请注意以前的工作中缺少细节元素。

作者这样的错误可能会导致相当疯狂的追逐。希望这篇文章能帮助其他人避免这种情况。

【讨论】:

【参考方案6】:

您只需要进一步阅读,您就会被介绍到 *ngIf 结构指令。

selectedHero.name 还不存在,因为用户还没有选择英雄,所以它返回 undefined。

<div *ngIf="selectedHero">
  <h2>selectedHero.name details!</h2>
  <div><label>id: </label>selectedHero.id</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="selectedHero.name" placeholder="name"/>
  </div>
</div>

*ngIf 指令将 selectedHero 保持在 DOM 之外,直到它被选中并因此变为真值。

This document 帮助我理解了结构指令。

【讨论】:

这帮助我得到了我想要的东西,谢谢+1 这对我也有帮助。事后这是有道理的,因为我的组件正在尝试渲染一个在异步操作完成时填充的对象。谢谢!【参考方案7】:

这一行

<h2>hero.name details!</h2>

*ngFor 之外并且没有hero 因此hero.name 失败。

【讨论】:

以上是关于Angular2:无法读取未定义的属性“名称”的主要内容,如果未能解决你的问题,请参考以下文章

无法读取未定义 angular2 ngif 的属性

angular2 i18n 无法读取未定义的属性“创建”

在angular2应用程序中运行ng serve时出现错误'无法读取未定义的属性'长度''

无法读取 nativescript angular2 中未定义的属性全局数组

NgZone/Angular2/Ionic2 TypeError:无法读取未定义的属性“运行”

Nodejs Promise TypeError:无法读取未定义的属性'then'