Angular 2:{{object}}可以正常工作,但{{object.child}}会抛出错误。

7

我已经使用Angular v1工作一段时间了,自从Angular v2进入测试版以来,一直在尝试。

现在我有了这段代码,但是无法使它正常工作,真的不知道为什么。 不知何故,当我打印{{profileUser | json}}时,一切都正常(profileUser是一个对象)。

但是当我想要打印该对象的子项(例如{{profileUser.name}}{{profileUser.name.firstName}})时,Angular会抛出以下错误:

EXEPTION:TypeError:undefined is not an object (evaluating 'l_profileUser0.name') in [ {{profileUser.name}} in ProfileComponent@4:11.

这真的让我感到困惑,应该是最简单的事情之一...顺便说一句,我刚开始接触TypeScript..

下面是一些代码 - ProfileService.ts

import { Injectable } from 'angular2/core';
import { Headers } from 'angular2/http';
import { API_PREFIX } from '../constants/constants';
import { AuthHttp } from 'angular2-jwt/angular2-jwt';
import 'rxjs/add/operator/map';

@Injectable()
export class ProfileService {

  API_PREFIX = API_PREFIX;

  constructor(private _authHttp:AuthHttp) {
  }

  getProfileData(username:string):any {
    return new Promise((resolve, reject) => {
      this._authHttp.get(API_PREFIX + '/users/username/' + username)
        .map(res => res.json())
        .subscribe(
          data => {
            resolve(data.data);
          },
          err => {
            reject(err);
          }
        )
      ;
    });
  }
}

这里是我的 ProfileComponent:

import {Component, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {ProfileService} from '../../services/profile.service';

@Component({
  selector: 'profile',
  templateUrl: './components/profile/profile.html',
  directives: [],
  providers: [ProfileService]
})

export class ProfileComponent implements OnInit {

  public username:string;
  public profileUser:any;

  constructor(private _profileService: ProfileService,
              private _params: RouteParams) {
    this.username = this._params.get('username');
  }

  ngOnInit() {
    this.getProfileData(this.username);
  }

  getProfileData(username:string):void {
    this._profileService.getProfileData(username)
      .then(data => {
        this.profileUser = data;
        console.log(data);
      })
    ;
  }
}

最后,是profile.html模板:
<pre> <!-- works! -->
{{profileUser | json}}
</pre>

或者...
<pre> <!-- throws the error -->
{{profileUser.name | json}}
</pre>

or..

<pre> <!-- throws the error -->
{{profileUser.name.firstName}}
</pre>

请注意,profileUser的格式如下:

{
  "id": "9830ecfa-34ef-4aa4-86d5-cabbb7f007b3",
  "name": {
    "firstName": "John",
    "lastName": "Doe",
    "fullName": "John Doe"
  }
}

希望有人能帮我,这真的阻碍了我对Angular v2的熟悉。谢谢!


2
Elvis运算符 - Eric Martinez
你为什么要用 Promise 包装它呢? - fxck
一开始我也没想到,猜猜你可以试试任何东西;-) - Aico Klein Ovink
@foxx 在 angular.io 文档中,他们正在使用 promises:https://angular.io/docs/ts/latest/tutorial/toh-pt4.html - Aico Klein Ovink
1
同意 @foox 的观点,因为 http.get 返回一个可观察对象(类似于承诺但更强大),所以在这里没有必要使用承诺。 这个 回答 可以帮助你。 - Thierry Templier
会研究一下,非常感谢! - Aico Klein Ovink
2个回答

21

实际上,您的profileUser对象是从HTTP请求加载的,而且一开始可能为nulljson管道只是执行了一个JSON.stringify

这就是您的错误消息所说的:undefined is not an object (evaluating 'l_profileUser0.name')

您需要确保您的profileUser对象不为null,才能获取其name属性等等。这可以使用*ngIf指令来实现:

<div *ngIf="profileUser">
  {{profileUser.name | json}}
</div>

数据到位时,HTML块将被显示。

正如Eric所说,Elvis运算符也可以帮助你。你可以使用{{profileUser?.name | json}}代替{{profileUser.name | json}}

希望能对你有所帮助, Thierry


非常感谢!这就做到了。但是这在v2中是新的吗?我们应该一直这样做吗? - Aico Klein Ovink
1
事实上,Angular1会隐式地完成这个操作。你不会看到任何错误信息或者显示内容。如果你对此问题感兴趣,可以参考这个链接。;-) - Thierry Templier

3
这是因为当你创建控制器时,profileUser 是未定义的。而且,当你使用 {{profileUser | json}} 过滤器时,json 知道你的数据是未定义的,因此不会执行任何操作。当最终定义了 profileUser 时,Angular 会更新整个内容,然后 profileUser | json 就可以正常工作了。但是,当你使用 {{ profileUser.anything | json}} 时,由于 profileUser 起始值为 undefined,因此会报错。
你可以解决它,只需在控制器开始时将变量设置为空的profile,就像这样:
profileUser = { name: {}};

这样,profileUser 就不会是 undefined 了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接