使用从 API 服务器检索的服务在组件之间共享数据
Sharing data between components using service retrieved from an API server
我正在从我在多个组件上使用的 API 服务器获取数据。但是,如果我尝试使用服务共享数据,则组件会在检索数据之前进行处理。
我可以检索每个组件中的数据,但是用户必须在加载每个页面(组件)之前等待数据被检索。数据不会改变,所以我希望能够 http.get() 一次数据并操纵各个组件中的视图。
我也可以将数据从父级传递给子级 - 但是,由于它们是多个页面,因此无法通过路由器和@Input() 共享数据。
现在,我正在尝试使用共享服务。该服务最终 returns 数据,但页面尝试在检索数据之前加载,这意味着没有显示任何数据。
app.component.html
<div class="router-body">
<router-outlet ></router-outlet>
</div>
api.service
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
console.log("in createData()");
this.people = people;
});
return of(this.people);
}
people.component
ngOnInit() {
this.apiService.createData(this.apiService.personURL)
.subscribe( people => {
console.log("data within people.component");
console.log(this.people);
this.people = people });
}
people.component this.people 得到 'undefined'
api.service returns 最终数据,但人员页面从未显示它。
我需要一个方法
1 - 一次拉取数据
2 - 在人员页面(或其他页面)上显示数据
我建议使用一个主题来分享这种数据:
首先在您的数据服务中创建一个 Person[] 类型的主题:
ppl$: Subject<Person[]> = new Subject();
然后定义一个getter:
getPplObs(): Observable<Person[]> {
return this.ppl$.asObservable();
}
当您在服务上设置数据时,将值传递给主题:
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
console.log("in createData()");
this.people = people;
this.ppl$.next(people);
});
}
现在你只需要在你的组件 ngOnInit 中订阅那个 Observable:
ngOnInit() {
this.apiService.getPplObs().pipe(takeUntil(this.unsubscribe$)).subscribe(ppl => this.people = ppls);
}
为了在组件销毁时正确取消订阅,我使用了 takeUntil。创建主题
unsubscribe$: Subject<boolean> = new Subject();
然后在 ngOnDestroy 生命周期中:
ngOnDestroy() {
this.unsubscribe$.next(true);
this.unsubscribe$.complete();
}
问候
对于以下内容,您总是先 returning people
,因为这是异步的。
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
// takes x time to complete
console.log("in createData()");
this.people = people;
});
// this line is executed while waiting for above response
return of(this.people);
}
我总是 return 一个 http 请求的可观察对象,或者 people
的一个可观察对象。可以使用tap
先将数据存入变量:
import { tap } from 'rxjs/operators';
// ...
people = <Person[]>[];
createData(url): Observable<Person[]> {
if (this.people.length) {
return of(this.people)
}
return this.http.get<Person[]>(url)
.pipe(
tap(people => this.people = people)
)
}
并记得在您的组件中取消订阅。
我正在从我在多个组件上使用的 API 服务器获取数据。但是,如果我尝试使用服务共享数据,则组件会在检索数据之前进行处理。
我可以检索每个组件中的数据,但是用户必须在加载每个页面(组件)之前等待数据被检索。数据不会改变,所以我希望能够 http.get() 一次数据并操纵各个组件中的视图。
我也可以将数据从父级传递给子级 - 但是,由于它们是多个页面,因此无法通过路由器和@Input() 共享数据。
现在,我正在尝试使用共享服务。该服务最终 returns 数据,但页面尝试在检索数据之前加载,这意味着没有显示任何数据。
app.component.html
<div class="router-body">
<router-outlet ></router-outlet>
</div>
api.service
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
console.log("in createData()");
this.people = people;
});
return of(this.people);
}
people.component
ngOnInit() {
this.apiService.createData(this.apiService.personURL)
.subscribe( people => {
console.log("data within people.component");
console.log(this.people);
this.people = people });
}
people.component this.people 得到 'undefined' api.service returns 最终数据,但人员页面从未显示它。
我需要一个方法 1 - 一次拉取数据 2 - 在人员页面(或其他页面)上显示数据
我建议使用一个主题来分享这种数据:
首先在您的数据服务中创建一个 Person[] 类型的主题:
ppl$: Subject<Person[]> = new Subject();
然后定义一个getter:
getPplObs(): Observable<Person[]> {
return this.ppl$.asObservable();
}
当您在服务上设置数据时,将值传递给主题:
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
console.log("in createData()");
this.people = people;
this.ppl$.next(people);
});
}
现在你只需要在你的组件 ngOnInit 中订阅那个 Observable:
ngOnInit() {
this.apiService.getPplObs().pipe(takeUntil(this.unsubscribe$)).subscribe(ppl => this.people = ppls);
}
为了在组件销毁时正确取消订阅,我使用了 takeUntil。创建主题
unsubscribe$: Subject<boolean> = new Subject();
然后在 ngOnDestroy 生命周期中:
ngOnDestroy() {
this.unsubscribe$.next(true);
this.unsubscribe$.complete();
}
问候
对于以下内容,您总是先 returning people
,因为这是异步的。
createData(url): Observable<any> {
this.http.get<Person[]>(url)
.subscribe(people => {
// takes x time to complete
console.log("in createData()");
this.people = people;
});
// this line is executed while waiting for above response
return of(this.people);
}
我总是 return 一个 http 请求的可观察对象,或者 people
的一个可观察对象。可以使用tap
先将数据存入变量:
import { tap } from 'rxjs/operators';
// ...
people = <Person[]>[];
createData(url): Observable<Person[]> {
if (this.people.length) {
return of(this.people)
}
return this.http.get<Person[]>(url)
.pipe(
tap(people => this.people = people)
)
}
并记得在您的组件中取消订阅。