我对Angular 2+非常陌生(大约一周),关于可观察部分有一个问题。
我有此服务:
export class GetProductsService {
allProducts;
constructor(private http: HttpClient) {
this.http.get('https://jsonplaceholder.typicode.com/posts').subscribe({
next: data => this.allProducts = data,
error: err => console.log(err)
});
}
getAllProducts() {
return this.allProducts;
}
在构造函数中,我获取请求以检索一些假的“产品”。
我将检索到的产品存储在属性中,以便将来可以更轻松地在该属性上使用其他功能。
现在这是我的问题:我有这个组件
export class AllProductsComponent implements OnInit {
allProducts: any;
constructor(private http: HttpClient, private productsService: GetProductsService) {}
ngOnInit(): void {
this.allProducts = this.productsService.getAllProducts();
}
}
这从ProductService OnInit检索product属性,但是考虑到它是可观察的,因此当另一个组件尝试检索allProducts属性时,它尚未从可观察的流中完全加载。
这将如何解决,我可以看到这是一个经常出现的问题,这就是为什么我还要求对该主题有一个更一般的理解。我了解它是异步的,我了解它是什么。
我尝试过的事情:
我尝试仅让Service返回Observable而不是设置其自己的状态,但是,当我实现检索特定产品的功能时,必须再次进行HTTP调用,而不是使用内部状态。
非常感谢您抽出宝贵的时间!
答案 0 :(得分:2)
如果希望在返回响应时得到通知,则应该从服务中返回可观察对象。
如果要避免在应用程序的生命周期内再次发出http请求,可以在第一个响应上缓存响应。
import { of } from 'rxjs';
import { tap } from 'rxjs/operators';
export class GetProductsService {
private cache = {
allProducts;
};
constructor(private http: HttpClient) { }
getAllProducts() {
if (this.cache.allProducts) {
return of(this.cache.allProducts);
}
return this.http.get('https://jsonplaceholder.typicode.com/posts').pipe(
tap(response => this.cache.allProducts = response)
);
}
}
然后您应该在组件中订阅此功能。
ngOnInit(): void {
this.productsService.getAllProducts().subscribe(products => {
this.allProducts = products;
});
}
注意-这是状态管理的一种非常简单的形式,我已经演示了这种模式,可以帮助您学习如何使用可观察对象。您会及时发现更多高级状态管理模式和工具。
答案 1 :(得分:0)
我使用这样的API服务:
@Injectable()
export class ApiService {
constructor(
private http: HttpClient
) { }
private setHeaders(): HttpHeaders {
const headersConfig = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
//...
return new HttpHeaders(headersConfig);
}
private formatErrors(errorResponse: any) {
return Observable.throw(errorResponse.error);
}
get(path: string, params: any = {}): Observable<any> {
return this.http.get(`${environment.api_url}${path}`, { headers: this.setHeaders(), params: params })
.catch(this.formatErrors);
}
}
并在我的ItemService中像这样使用它:
query(itemSlug: string): Observable<{ items: Item[] }> {
return this.apiService
.get('/items/' + itemSlug);
}
在我的控制器中,我像这样使用ItemService:
this.itemsService.query(this.item.slug).subscribe(data => {
this.items = data.items;
});
有关此方法的更多信息,请参见https://github.com/gothinkster/angular-realworld-example-app