首页 > 解决方案 > 使用持久数据的正确方法

问题描述

items只尝试从数据库中获取一次(我不希望它们改变)。当我最初加载home-page.component.tsHomePageComponent.items时,如果我导航离开HomePageComponentProfilePageComponent然后返回到,HomePageComponent因为itemsService.items$已经解决了订阅回调不会重新运行并且不会重新初始化,所以会正确设置HomePageComponent.items。这是我正在使用的当前解决方法,但感觉太笨拙,无法正确处理这种情况。

主页.component.ts

ngOnInit() {
    this.itemsService.items$.subscribe((items:item) => {
      // Is only called once after items are initalially fetched over http
      this.items = items;
      this.itemsService.addItems(items);
    });

    if(this.itemsService.foundItems){
      this.items= this.itemsService.items;
    }
}

items.service.ts

export class ItemsService {

  private items = new BehaviorSubject(null);
  items$ = this.items.asObservable();

  foundItems = null;

  constructor(private httpClient: HttpClient){
    this.items.next(httpClient.post<any>(myUrl,myQuery).subscribe(this.items));
  }

  addItems(items){
   this.foundItems = items;
  }
}

标签: angularrxjsobservable

解决方案


组件不应该知道任何缓存,您需要对其进行抽象。该服务可以缓存检索到的项目,然后将这些项目返回给使用of. 服务本身可以使用 缓存调用结果tap

主页.component.ts

ngOnInit() {
    this.itemsService.getItems().subscribe((items) => {
      this.items = items;
    });
}

items.service.ts

import { map, tap } from 'rxjs/operators';
import { of } from 'rxjs';

export interface IItem {
}

export class ItemsService {

  items: IItem[];

  constructor(private httpClient: HttpClient){
  }

  getItems() : Observable<IItem[]> {
    return this.items 
        ? of(this.items)
        : this.httpClient.get<IItem[]>(myUrl).pipe(tap((data) => this.items = data));
  }
}

出于示例的目的,我添加了一个名为 IItem 的接口,以便我可以强输入调用和签名。您可以将其替换为您需要的任何接口类型。


推荐阅读