【问题标题】:Is there a way to save HTTP response data in order to not recall HTTP service?有没有办法保存 HTTP 响应数据以便不调用 HTTP 服务?
【发布时间】:2019-03-25 22:18:50
【问题描述】:

我会尽力解释,这是我的第一个 Ionic 应用程序。

我的目标是创建一个简单的仪表板,其中包含从 JSON 文件中获取的一些类别,调用 Cordova HTTP 本地服务。 单击仪表板中的一个类别时,它应该加载另一个仪表板,其中包含基于我通过 [routerLink] 指令发送的特定 ID 参数的类别。

它按预期工作,但是当我点击“后退”按钮并返回主仪表板时,如果我点击相同的类别,则会触发 ngOnInit() 方法并且 http 服务会再次获取数据。

如果尚未获取特定类别数据,我想单击一个类别并仅在第一次调用 http 服务,而在第二次单击此类别时仅显示该数据。

我已尝试检查 this.category_sources,但可能每次我点击“返回”按钮时组件都会被破坏并且数据丢失。

  ngOnInit() {
    this.retrieveID();
    console.log("OnInit");
    this.presentLoading();
    this.CategoryCtrl();
  }

  retrieveID() {
    this.sub = this.route.params.subscribe(params => {
      this.id = +params['id'];
    });
  }

  CategoryCtrl() {
    if (this.category_sources) {
      console.log("Data already existing");
      this.stopLoading();
    } else {
    this.serverService.getReviewsCategory(this.id)
    .subscribe((data) => {
      this.fetched = true;
      this.category_sources = data['reviews'];
      this.info = data['info'];
      this.banner = data['banner'];
      this.fetched = true;
      this.stopLoading();
    });
  }
}

  backClicked() {
    console.log("Back clicked");
    this.location.back();
  }

  async presentLoading() {
    const loadingController = this.loadingController;

    const loadingElement = await loadingController.create({
      spinner: 'crescent',
    });
    return await loadingElement.present()
  }

  async stopLoading() {
    return await this.loadingController.dismiss();
  }

}

【问题讨论】:

  • 将发送/接收数据的代码移动到服务中,在服务内部缓存数据并使用此缓存数据而不是向 Web 服务器发送新请求 (blog.thoughtram.io/angular/2018/03/05/…)。另一种方法是使用 http 拦截器。
  • 我在这里有相同主题的答案stackoverflow.com/questions/55136593/…
  • 谢谢大家! @malbarmawi 缓存服务就像一个魅力!我只有最后一个问题...我有一个 LoadingController,我曾经在 ngOnInit 方法中呈现Loading(),在订阅正文中使用 stopLoading()。它在从 Http 服务(第一次)获取数据时工作,但是当数据来自缓存时,微调器不会停止其执行..在这种情况下不会执行订阅主体,因此微调器会继续加载并且永远不会关闭..我想仅在第一次 http 调用期间加载微调器,并且不再显示它,但始终执行 ngOnInit 并使用它 presentLoading ()
  • @Federico 我已经根据你的情况添加了一个答案,你不需要检查数据是否被缓存,它将在服务器服务类中处理这个????
  • 我遵循了你写的所有内容并且它有效,“返回”按钮也有效,但如果我在我的选项卡中单击“主页”,则会创建一个新实例,因此会再次调用该服务,即使数据来自缓存,完成请求需要很长时间。我没有连接问题,所以我不明白问题可能出在哪里......

标签: javascript angular typescript http ionic-framework


【解决方案1】:

您可以创建一个全局服务来处理缓存,而无需本地存储,只需将数据保存在内存(对象)中,这样当应用关闭时,数据就会消失

现金服务 ?

@Injectable({ providedIn: "root"})
export class CashingService {

  private __cach = {}
  isCashed(url: string) {
    return this.__cach[url];
  }

  getData(url: string) {
    return this.__cach[url]
  }

  setData(url) {
    return (data) => {
      if (data && (data instanceof Error) === false)
        this.__cach[url] = data
    };

  }

  reset() {
    this.__cach = {};
  }
}

实施服务?

@Injectable()
export class ServerService {

  constructor(private http: HttpClient , private _c:CachingService ) { }

  public getReviewsCategory(url: any): Observable<any> {

    if (this._c.isCashed(url)){
     return of(this._c.getData(url));
    } else {
    return this.http.get(url)
      .pipe(
       tab(this._c.setData(url)),
       catchError(this.handleError('apiGetRequest'))
      );
    }

  }
}

从服务中获取数据

组件✨

  ngOnInit() {
    this.retrieveID();
    console.log("OnInit");
    this.presentLoading();
    this.CategoryCtrl();
  }

  CategoryCtrl() {

    this.serverService.getReviewsCategory(this.id)
    .subscribe((data) => {
      this.category_sources = data['reviews'];
      this.info = data['info'];
      this.banner = data['banner'];
      this.fetched = true;
      this.stopLoading(); // stop the spinner
    });
  }
}

您可以查看有关 rxjs 等不同方式处理 chaching 的答案How to perform caching http get request in angular 5?

【讨论】:

    【解决方案2】:

    我有想法,点击成功后可以使用:(set,get) data,保存localStorage 让数据 = localStorage.setItem('categories'); 让数据 = localStorage.getItem('categories');

    //FRONT-END ANGULA
    
    categories:any={}
    
    Constructor(){
      //check categories localStorage
      let dataCatogories = localStorage.getItem('categories');
      if(dataCatogories.length>0){
      
        //You can handle it here 
        this.categories = dataCategories;
      }
    
    }
    
    
    //CLick categories
    getAllCatogories = ()=>{
      this.http.get('APP_URL').subscribe(item=>{
       localStorage.setItem("categories",item);
      }
    
    }

    【讨论】:

      猜你喜欢
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      相关资源
      最近更新 更多