Angular 2 组件无法从服务中检索数据
Angular 2 component cannot retrieve data from service
情况很简单 - 我正在尝试从 Angular 2 服务获取数据,但目标数组始终为空。我可以看到对 api return 数据和状态 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;
}
}
基本上,当您这样做时:
@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();
})
}
}
您调用您的网站 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);
}
}
这一次,只要有数据,items
就会包含它们。但是,这样做并不是最佳的,因为它可能是您的组件在 HTTP 调用完成之前加载,在这种情况下,您也会得到一个空数组。最好的方法是 returns observable(return by map
)并让您的组件订阅它,或者创建一个新的 observable 在初始化 items
时触发。
这是第一种可能性的例子:http://plnkr.co/edit/DD8fqa2dJGksCtOlolO2?p=preview
这种方法有效,唯一的问题是如果你调用 "loadItems" 两次,HTTP 调用将完成两次。如果你想要一些缓存,必须使用 Observables 开发更高级的东西。
情况很简单 - 我正在尝试从 Angular 2 服务获取数据,但目标数组始终为空。我可以看到对 api return 数据和状态 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;
}
}
基本上,当您这样做时:
@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();
})
}
}
您调用您的网站 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);
}
}
这一次,只要有数据,items
就会包含它们。但是,这样做并不是最佳的,因为它可能是您的组件在 HTTP 调用完成之前加载,在这种情况下,您也会得到一个空数组。最好的方法是 returns observable(return by map
)并让您的组件订阅它,或者创建一个新的 observable 在初始化 items
时触发。
这是第一种可能性的例子:http://plnkr.co/edit/DD8fqa2dJGksCtOlolO2?p=preview
这种方法有效,唯一的问题是如果你调用 "loadItems" 两次,HTTP 调用将完成两次。如果你想要一些缓存,必须使用 Observables 开发更高级的东西。