我有两个组件,博客和帖子。帖子位于Blog组件中。仅在第一次使用服务时,数据不会显示在帖子视图下。如果我来回两个不同的视图,那么数据会出现。那么,如何在未加载数据之前停止渲染视图呢?
我正在尝试从以下API(https://jsonplaceholder.typicode.com/posts)获取数据。如果我直接在组件中使用HTTP get,那么提取工作正常,
this.http.get('https://jsonplaceholder.typicode.com/posts')
.map((response) => {
return response.json();
})
.subscribe((data) => {
// console.log(data);
this.posts = data;
});
但是当我将代码移动到服务时会出现问题。
我有一个博客服务,
import { Injectable } from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class BlogService {
posts = [];
constructor(private http: Http) { }
fetchAllPosts() {
this.http.get('https://jsonplaceholder.typicode.com/posts')
.map((response) => {
return response.json();
})
.subscribe((data) => {
// console.log(data);
this.posts = data;
});
}
getAllPosts() {
// console.log(this.posts);
return this.posts.slice();
}
}
我正在从博客组件
调用fetchAllPosts()ngOnInit() {
this.blogService.fetchAllPosts();
}
然后在postsComponent中,我正在调用getAllPosts()。
ngOnInit() {
this.posts = this.blogService.getAllPosts();
console.log(this.posts);
}
以下是博客组件
<div class="container">
<app-posts></app-posts>
</div>
答案 0 :(得分:1)
注意:您应该避免在服务中使用.subscribe()
export class BlogService {
posts = [];
constructor(private http: Http) { }
fetchAllPosts() {
this.http.get('https://jsonplaceholder.typicode.com/posts')
.map((response) => {
return response.json();
})
}
getAllPosts() {
// console.log(this.posts);
return this.posts.slice(); // I don;t know why are you using .slice() here. It should be return this.posts();
}
}
posts:[]; // I believe you use this posts object in PostComponent template
ngAfterViewInit() {
this.posts = this.blogService.getAllPosts();
console.log(this.posts);
}
// if above block doesn't work for you , you can use setTimeOut()
ngAfterViewInit() {
setTimeout(()=>{
this.posts = this.blogService.getAllPosts();
console.log(this.posts);
},500)
}
constructor(private bgService:BlogService){ // added service
blogService
.fetchAllPosts()
.subscribe((data) => {
// console.log(data);
this.bgService.posts = data; // look at here, this will update posts object
});
}
答案 1 :(得分:0)
使用*ngIf
,如下所示
<div class="container">
<div *ngIf="posts?.length > 0">
<app-posts></app-posts>
</div>
</div>
答案 2 :(得分:0)
所以......还有一个选择。这允许服务保留数据并与应用程序的其他部分共享:
@Injectable()
export class BlogService {
private _posts() = [];
get posts() {
return _posts;
}
constructor(private http: Http) { }
fetchAllPosts() {
this.http.get('https://jsonplaceholder.typicode.com/posts')
.map((response) => {
return response.json();
})
.subscribe((data) => {
// console.log(data);
this.posts = data;
});
}
}
通过使用getter而不是方法(例如getAllPosts),组件可以绑定到此属性,数据一到达就会被绑定,并由http get设置。
PostComponent 是:
get posts() {
return this.blogService.posts;
}
取代您拥有的ngOnInit代码。
这样你就可以绑定到PostComponent的html中的任何位置。该值最初是未定义的,因此您需要使用@aravid显示的技术并确保HTML可以处理未定义的。
当数据从服务器到达时,更改检测将确保在绑定属性中更新该值。
我有一个在这里演示此技术的plunker:https://plnkr.co/edit/BZT2oe8YmRS717lN0nPh?p=preview