从 angular2 中由服务填充的列表中获取对象

get objects from a list populated by service in angular2

我是 angular2 的新手,正在尝试做一件非常简单的事情。我有一个本地 json 文件,我正在通过 http.get 访问它以使用服务获取数据。此服务 return 一个数据列表,我想从中访问一个对象并在屏幕上呈现。我不想使用 ngFor,因为我有 Previous,Next 功能,我想在我的用户点击时将对象一个一个地推送到视图中。但是我的渲染失败了,在下面的代码中看起来像 "promoObj" "undefined" 并且无法弄清楚原因。下面是我的代码 -

Component.ts

import { Component } from '@angular/core';
import { TitleService } from '../services/services.intrests';
import { OnInit } from '@angular/core/src/metadata/lifecycle_hooks';
import { Promo } from '../services/model';


@Component({
    selector: 'promo-banners',
    templateUrl: 'src/components/promotion/promotion-template.html',
    styleUrls: ['./static/css/app.css']
})
export class PromotionWidget implements OnInit {

    promoList: Array<Promo>;
    promoObj: Promo;



    constructor(private titleSvc: TitleService) { }

    ngOnInit() {
        this.retrievePromotions();
        //I want to do something like this and push the first object in view when initialized
        this.promoObj = this.promoList[0];

    }
    retrievePromotions() {
        this.titleSvc.getTitle().subscribe(data => {
            this.promoList = data;
        });

    }


}

在上面的代码中,Promo 是一个 class 并且包含预期来自 json 的属性。

下面是我的服务文件 service.ts

import { Injectable } from '@angular/core';

import { Http, Response,Headers,RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
@Injectable()

export class TitleService {
    constructor(private http: Http) { }

    getTitle() {
        console.log("again");
        return this.http.get('./static/json/title.json').map((res: Response) => res.json());
    }

}

View.html

 <div style="max-width: 30%;float: left;" class="promo-card">
        <h2>{{promoObj.title}}</h2>

    </div>

我知道我在做什么傻事但不知道是什么。请帮忙。

这是一个典型的异步问题。在你拥有它的地方做 this.promoObj = this.promoList[0]; 是行不通的。您的网络请求尚未完成,因此您的 this.promoList 为空。这将解决您的问题:

ngOnInit() {
    this.retrievePromotions().subscribe(data => {
        this.promoList = data;
        this.promoObj = this.promoList[0];
    });
}



retrievePromotions() {
    return this.titleSvc.getTitle();
}

问题的另一部分是 html 模板在初始化之前试图访问 promoObj 上的属性。您可以通过几种方式解决此问题:

使用 ngIf 来保护 属性 访问:

<div *ngIf="promoObj != null" style="max-width: 30%;float: left;" class="promo-card">
        <h2>{{promoObj.title}}</h2>

    </div>

或使用 "safe navigation operator":

<div style="max-width: 30%;float: left;" class="promo-card">
        <h2>{{promoObj?.title}}</h2>
    </div>

正如 matmo 之前提到的,您的代码 this.promoObj = this.promoList[0]; 正在尝试访问并分配一个尚不存在的值在组件的初始化状态。在订阅中执行此操作可确保网络请求已完成并且您已从请求中获取数据。

import { Component } from '@angular/core';
import { TitleService } from '../services/services.intrests';
import { OnInit } from '@angular/core/src/metadata/lifecycle_hooks';
import { Promo } from '../services/model';


@Component({
    selector: 'promo-banners',
    templateUrl: 'src/components/promotion/promotion-template.html',
    styleUrls: ['./static/css/app.css']
})
export class PromotionWidget implements OnInit {

    promoList: Array<Promo>;
    promoObj: Promo;



    constructor(private titleSvc: TitleService) { }

    ngOnInit() {
        this.retrievePromotions();
    }

    retrievePromotions() {
        this.titleSvc.getTitle().subscribe(data => {
            this.promoList = data;
            this.promoObj = this.promoList[0];
        });

    }


}