Angular 2组件无法从服务中检索数据

Angular 2组件无法从服务中检索数据,angular,angular2-services,Angular,Angular2 Services,情况很简单-我试图从Angular 2服务获取数据,但目标数组总是空的。我可以看到对api的调用返回数据和状态200,并且控制台中并没有错误。 这是我的基本服务: import {Injectable} from "@angular/core"; import {Http, Response} from '@angular/http'; @Injectable() export class DataService { items = []; constructor(privat

情况很简单-我试图从Angular 2服务获取数据,但目标数组总是空的。我可以看到对api的调用返回数据和状态200,并且控制台中并没有错误。 这是我的基本服务:

import {Injectable} from "@angular/core";
import {Http, Response} from '@angular/http';

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            })
    }
}
下面是组件:

import {Component, Input} from '@angular/core';
import {DataService} from './../../services/data-service';

@Component({
    selector: 'items-list',
    template: `
        <div class="container">
    <div class="items" *ngFor="let item of items|sort:'DESC';let i = index;trackBy: item?.id">
    <a href="/items/{{item.id}}">
        <mdl-card class="demo-card-square" mdl-shadow="2" mdl-card-expand>
        <mdl-card-media>
        <img src="{{item.imgUrl}}" alt="{{item.name}}" style="max-width: 100%">
         </mdl-card-media>
            <mdl-card-title mdl-card-expand>
                <h2 mdl-card-title-text>{{item.name}}</h2>
            </mdl-card-title>
            <mdl-card-supporting-text>
                {{item.shortDescription}}
            </mdl-card-supporting-text>
            <mdl-card-actions mdl-card-border>
                <h6 class='mdl-color-text--grey-600'>От {{item.priceFrom}} рублей.</h6>
            </mdl-card-actions>
        </mdl-card>
        </a>
    </div>
</div>
`,
    styles: [
        `
.container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-around;
    align-content: space-around;
    align-items: stretch;
    width: 100%;
}

.items{
    margin: auto;
    padding-top: 1%;
    padding-bottom: 1%;
}

a {
text-decoration: none;
}

`
    ]
})

export class ItemsList {
    @Input() items = [];
    constructor(private dataService: DataService) {
        this.items = dataService.items;
    }
}
从'@angular/core'导入{Component,Input};
从“/../../services/data service”导入{DataService};
@组成部分({
选择器:“项目列表”,
模板:`
`,
风格:[
`
.集装箱{
显示器:flex;
弯曲方向:行;
柔性包装:包装;
证明内容:周围的空间;
对齐内容:周围的空间;
对齐项目:拉伸;
宽度:100%;
}
.项目{
保证金:自动;
垫面:1%;
垫底:1%;
}
a{
文字装饰:无;
}
`
]
})
导出类项目列表{
@输入()项=[];
构造函数(专用数据服务:数据服务){
this.items=dataService.items;
}
}

基本上,当您执行此操作时:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            })
    }
}
您调用web API并只映射结果,但不将其分配给任何对象。也许你可以这样修改它:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            }).subscribe(data => this.items = data);
    }
}
这一次,一旦数据存在,
项将包含它们。但是,这样做并不是最优的,因为可能是在HTTP调用完成之前加载组件,在这种情况下,您也会得到一个空数组。最好是返回可观察项(通过
map
返回)并让组件订阅它,或者创建一个新的可观察项,当
初始化时触发

以下是第一种可能性的示例:


这种方法是有效的,唯一的问题是,如果调用“loadItems”两次,HTTP调用将执行两次。如果您需要一些缓存,则必须使用可观察对象开发更高级的东西。

基本上,当您这样做时:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            })
    }
}
您调用web API并只映射结果,但不将其分配给任何对象。也许你可以这样修改它:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            }).subscribe(data => this.items = data);
    }
}
这一次,一旦数据存在,
项将包含它们。但是,这样做并不是最优的,因为可能是在HTTP调用完成之前加载组件,在这种情况下,您也会得到一个空数组。最好是返回可观察项(通过
map
返回)并让组件订阅它,或者创建一个新的可观察项,当
初始化时触发

以下是第一种可能性的示例:


这种方法是有效的,唯一的问题是,如果调用“loadItems”两次,HTTP调用将执行两次。如果您需要一些缓存,则必须使用可观察对象开发更高级的功能。

谢谢您的回答,您能给我指出一些有关使用可观察对象的信息吗?我在回答中添加了一个plunker,向您展示一种简单的方法来做您想要的事情。谢谢您的回答,你能给我指出一些关于使用可观察物的信息吗?我在我的答案中添加了一个plunker,以向你展示一种简单的方法来做你想做的事情。