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

时间:2016-09-28 18:42:50

标签: angular angular2-template

我开始学习Angular2。我一直在关注angular.io提供的英雄教程。 一切正常,直到被使用模板的HTML杂乱所困扰,我在其位置使用模板URL,并将HTML移动到名为hero.html的文件。 生成的错误是"无法读取属性' name'未定义"。 奇怪的是,可以访问指向一组对象的英雄变量,以便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>

这是一张照片:

enter image description here

7 个答案:

答案 0 :(得分:109)

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

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

还需要分离[ngModel]和(ngModelChange)中的[(ngModel)],因为您无法分配使用elvis运算符的表达式。

我也认为你的意思是:

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

而不是:

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

答案 1 :(得分:23)

你只需要进一步阅读,你就会被引入* ngIf结构指令。

selectedHero.name尚不存在,因为用户尚未选择英雄,因此返回undefined。

    <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/image_view"
            android:layout_margin="5dp"
            android:layout_alignParentEnd="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitStart"
            android:adjustViewBounds="true"
            android:src="@drawable/crayon" />

</RelativeLayout>

* ngIf指令使selectedHero脱离DOM直到被选中,因此变得真实。

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

答案 2 :(得分: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>

请注意以前的努力中缺少细节元素。

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

答案 3 :(得分:4)

这样可以避免这种情况,您也可以将组件的selectedHero成员初始化为空对象(而不是将其保留为未定义)。

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

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

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

答案 4 :(得分:2)

这一行

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

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

答案 5 :(得分:0)

这对我有用:

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

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

并确保您也初始化了selectedHero

selectedHero: Hero = new Hero();

答案 6 :(得分:-1)

在Angular中,有Elvis支持运算符来防止视图渲染失败。他们称其为安全的导航运营商。请看下面的例子

当前人员名称为{{nullObject?.name}}

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

https://trungk18.com/experience/uncaught-type-error/