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应用程序中运行ng serve时出现错误'无法读取未定义的属性'长度''
无法读取 nativescript angular2 中未定义的属性全局数组