Angular 2 - 查看单个数据记录

时间:2017-07-03 15:53:33

标签: javascript angular

我是Angular的新手,所以我无法弄清楚如何根据我想要完成的事情来形成我的问题,但现在就这样了。

我有一个从服务中获取单个用户记录的组件。然后,我想在我的UI上显示这些用户详细信息。在我的代码的其他部分,它们总是多个记录,所以我使用*ngFor并循环数据数组。但是,由于这只是一个结果,我不太清楚如何实现这一目标。

组件:

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { UserRecord } from '../shared/user-record.interface';
import { UserService } from '../shared/user.service';

@Component({
    selector: 'app-view-record',
    templateUrl: './view-record.component.html',
    styleUrls: ['./view-record.component.css']
})
export class ViewRecordComponent implements OnInit {

    private record: UserRecord[];
    private errorMessage: any = '';
    private loaded = false;
    private RecordID: number; // User ID of who we are looking at

    constructor(private _crudService: UserService,
        private activatedRoute: ActivatedRoute) { }

    ngOnInit() {

        // Get the userID from the activated route
        this.activatedRoute.params.subscribe((params: Params) => {
            this.RecordID = params['id'];
        });

        // Call our service and pass the userID
        this._crudService.getRecord(this.RecordID)
            .then(res => {
                this.record = this._crudService.record;
                return this._crudService.getRecord(this.RecordID);
            })
            .then(res => {
                console.log(this.record)
                this.loaded = true;
            })
            .catch(err => { console.error(err); });
    }

}

服务:

getRecord(userID: number) {

        const headers: Headers = new Headers({
            "Authorization": this._frameworkService.getSessionInfo().token
        });
        return new Promise((resolve, rejects) => {
            this._http.post(this.baseUrl + '/fetchRecord', { "userID": userID }, { "headers": headers })
                .map(res => res.json())
                .subscribe((data) => {
                    if (data) {
                        this.record = data;
                    }
                    resolve(true);
                });
        });
    }

界面:

export interface UserRecord {
    RecordID: number;
    QID: string;
    FavoriteColor?: string;
    FavoriteNumber?: number;
    FavoriteActor?: string;
    MetaInsertUTC: string;
    MetaUpdateUTC: string;
    FirstName: string;
    LastName: string;
    NTID: string;
}

服务结果:

[  
   {  
      "RecordID":"55",
      "QID":"Q00019204",
      "FavoriteColor":"Blue",
      "FavoriteNumber":"6",
      "FavoriteActor":"Bob",
      "MetaInsertUTC":"2017-06-29 18:47:01.750",
      "MetaUpdateUTC":null,
      "FirstName":"Jim",
      "LastName":"Bobs",
      "NTID":"bobby"
   }
]

在我的组件HTML中,我尝试了{{record.FirstName}},但收到错误ViewRecordComponent.html:16 ERROR TypeError: Cannot read property 'FirstName' of undefined

由于这不是一组数据结果,我不知道*ngFor如何适用于用例。

我认为既然我的组件将数据存储在record对象中,我应该能够从UI访问它吗? console.log显示所有正确的数据点。

如何在组件HTML中引用用户FirstName?希望我至少走在正确的道路上。

2 个答案:

答案 0 :(得分:1)

您的回复似乎是一个包含对象的数组,因此record.FirstName不存在,但record[0].FirstName确实存在。

当涉及到视图时,请记住使用安全导航操作符或*ngIf,这样就不会遇到DeborahK提到的未定义问题。 Observable type error: cannot read property of undefined

此外,关于如何处理Angular中的http的一些建议......我会做类似以下的事情......

getRecord(userID: number) {
    const headers: Headers = new Headers({
        "Authorization": this._frameworkService.getSessionInfo().token
    });
    return this._http.post(this.baseUrl + '/fetchRecord', { "userID": userID }, { "headers": headers })
       .toPromise()
       .then(res => res.json()[0]) // get the object only
       .catch(err => { console.error(err); });
}

和组件:

this._crudService.getRecord(this.RecordID)
   .then(res => {
       this.record = res;
   });

但这完全取决于你:)

答案 1 :(得分:0)

从Http获取数据是异步的。这意味着当首次显示页面时,数据尚未存在。

有几种方法可以解决这个问题:

一种选择是使用“?” (安全导航)运算符:# CentOS-Base.repo # # This file uses a new mirrorlist system developed by Lance Davis for CentOS. # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # # [base] name=CentOS-$releasever - Base mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os #baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/ gpgcheck=1 gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-centos6 这样可以更好地处理空值。有关详细信息,请参阅此链接:https://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths

另一种选择是在HTML代码周围使用* ngIf。 {{record?.FirstName}}

因此,当您的页面首次显示时,它不会生成尚未设置记录的错误。一旦检索到数据,绑定就会注意到更改并适当地更新UI。

以下是我的服务方法之一:

*ngIf='record'

以下是对该服务的调用:

getProducts(): Observable<IProduct[]> {
    return this._http.get(this._productUrl)
        .map((response: Response) => <IProduct[]> response.json())
        .catch(this.handleError);
}

请注意,订阅位于调用服务的组件中,而不在服务本身中。