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

Angular2:无法读取未定义的属性“name”,angular,angular2-template,Angular,Angular2 Template,我开始学英语了。我一直在关注angular.io上提供的英雄教程。 所有这些都很好地工作,直到我被使用模板的HTML的混乱所困扰,我使用了模板URL来代替它,并将HTML移动到一个名为hero.HTML的文件中。 生成的错误是,无法读取未定义的属性“name”。 奇怪的是,可以访问指向对象数组的heroes变量,以便ngFor根据数组中对象的数量生成正确数量的li标记。但是,无法访问数组对象的数据。 此外,即使是一个包含一些文本的简单变量,也不会使用HTML中的{{}括号显示(请参阅提供的代码)

我开始学英语了。我一直在关注angular.io上提供的英雄教程。 所有这些都很好地工作,直到我被使用模板的HTML的混乱所困扰,我使用了模板URL来代替它,并将HTML移动到一个名为hero.HTML的文件中。 生成的错误是,无法读取未定义的属性“name”。 奇怪的是,可以访问指向对象数组的heroes变量,以便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>
这是一张照片:

这条线

<h2>{{hero.name}} details!</h2>
在*ngFor之外,没有hero,因此hero.name失败。

模板中的变量selectedHero为空,因此无法按原样绑定selectedHero.name。你需要使用?。在这种情况下:

还需要将[ngModel]分为[ngModel]和ngModelChange,因为您不能为使用elvis运算符的表达式赋值

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

{{selectedHero?.name}}详细信息! 而不是:

{{hero.name}}详细信息!
您只需要进一步阅读,就可以了解*ngIf structural指令

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之外,直到它被选中,因此变得真实


帮助我理解结构指令

之所以出现此错误,是因为您遵循了英雄教程中写得不好的说明。我遇到了同样的事情

具体而言,在“模板中显示英雄姓名”标题下,它指出:

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

后跟此代码块:

<h2>My Heroes</h2>
<ul class="heroes">
  <li>
    <!-- each hero goes here -->
  </li>
</ul>
请注意,以前的工作中没有细节元素


作者犯了这样的错误,可能会引起很大的麻烦。希望本文能帮助其他人避免这种情况。

为了避免这种情况,您最好将组件的selectedHero成员初始化为空对象,而不是将其保留为未定义

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

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

  onSelect(hero: Hero):void{
      this.selectedHero = hero;
  }
}
这对我很有用:

export class Hero{
   id: number;
   name: string;

   public Hero(i: number, n: string){
     this.id = 0;
     this.name = '';
   }
 }
并确保您也同样初始化了selectedHero

selectedHero: Hero = new Hero();

在Angular中,有支持elvis运算符?。以防止视图渲染失败。他们称之为安全导航操作员。以下面的例子为例:

The current person name is {{nullObject?.name}}

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

谢谢。您已经大致确定了问题所在。然而,我仍然有问题。我将{{hero.name}更改为{{selectedHero.name}},但仍然得到相同的错误。我还按照您的指示更新了输入,但错误仍然存在。当标记行被注释掉时,除了{{selectedHero.name}}详细信息以外的所有内容都被注释掉了!工作正常。因此,我知道selectedHero对象使用不正确。对不起,我忘记了代码上的elvis运算符。我编辑了答案。它应该是:{{selectedHero?.name}太棒了!我刚刚加了一个?我的代码工作得很好。谢谢,添加?在我的属性修复了条件数据绑定(如果属性存在)的问题之后。你能详细解释一下你的意思吗?因为你不能给一个使用elvis运算符的表达式赋值。我没有做你描述的任何ngModelChange的事情,我的elvis操作符工作得很好,就像这个[value]=这个.data?.office?。name@TetraDev您的示例之所以有效,是因为它只是一个数据绑定[]指令,而不是一个事件绑定。如果angular能够解析语句并识别这些情况就好了,但目前还没有。看这帮我得到了我想要的,谢谢+1这也帮了我。这在事后是有意义的,因为我的组件试图呈现一个在异步操作完成时填充的对象。谢谢
selectedHero: Hero = new Hero();
The current person name is {{nullObject?.name}}