【问题标题】:Keep list updated with Ionic 2 / Angular 2使用 Ionic 2 / Angular 2 更新列表
【发布时间】:2016-12-12 02:31:09
【问题描述】:

我有一个使用 Angular 2 的 Ionic 2 开发的应用程序。

我想通过两种方式更新我的组件列表。

  1. 自动 - 如果没有更新或上次更新已更新,则刷新 30 多分钟前。
  2. 手动 - 如果用户不想等到下一次更新,他可以随时手动更新。

当用户离开页面时取消自动刷新,当他回来时重新初始化。我不想在用户进入页面时立即更新,而是在自上次更新后 30 分钟完成时才更新。

实现这一目标的最佳方法是什么?我想知道更新是否会发生冲突,如果是,如何取消所有并仅继续最后一次调用?

我是 Angular 2 的新手,对 Observables 有点困惑。这是我所拥有的:

import { Component } from '@angular/core';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/mergeMap';
import "rxjs/add/observable/interval";

import { NavController } from 'ionic-angular';

import { EventData } from '../../providers/event-data';

@Component({
  selector: 'page-event-list',
  templateUrl: 'event-list.html'
})
export class EventListPage {
  public events = [];
  private subscription;

  constructor(public navCtrl: NavController, public eventData: EventData) {}

  ionViewDidEnter() {
    this.load();
  }

  ionViewDidLeave() {
    this.cancel();
  }

  load() {
    let observable = Observable
      .interval(10000)
      .flatMap(() => {
        return this.eventData.load();
      })
      .share();

    this.subscription = observable
      .subscribe(events => this.events = events, error => console.log(error));

    return observable;
  }

  reload(refresher) {
    this.load()
      .subscribe(null, null, () => refresher.complete());
  }

  cancel() {
    if (this.subscription.closed) {
      return;
    }

    this.subscription.unsubscribe();
  }

}

【问题讨论】:

    标签: http angular ionic2 rxjs


    【解决方案1】:

    您可以使用以下方法解决此问题:

    // this can be a click-event, or anything else, in this case it'll just be a simple manualTrigger$.next();
    let manualTrigger$ = new Rx.Subject();
    
    // the timer will trigger immediately and then every 30seconds
    let intervalTrigger$ = new Rx.Observable.timer(0, 30000);
    
    // this is our actual combination "logic", a simple "switchMapTo"
    // switchMap switches to a new subscription of our timer each time manualTrigger$ triggers and discards the old one
    let resetIntervalWhenTriggeredManually$ = manualTrigger$
      .switchMapTo(intervalTrigger$);
    
    // make sure to unsubscribe when the view is destroyed or just use the async-pipe in your template!
    resetIntervalWhenTriggeredManually$
      .flatMap(makeRestCall); // here you insert your rest-call
      .subscribe(
          data => console.log("Data is:", data),
          error => console.error("Error: " + error)
      );
    

    您还可以在此处查看此 jsbin 以获取运行示例:http://jsbin.com/titujecuba/edit?js,console


    您希望在用户离开/进入页面时自动停止/继续更新的部分,不能用纯 rxjs 完成,您必须在最后更新的某个地方保留一个日期,并检查小句:

    // check every second
    const thirtyMinutes: number = 1000 * 60 * 30;
    let lastUpdated: number = -1;
    let intervalTrigger$ = new Rx.Observable.timer(0, 1000);
    let resetIntervalWhenTriggeredManually$ = manualTrigger$
      .do(() => lastUpdated = -1) // rest the last update to force an update
      .switchMapTo(intervalTrigger$)
      .filter(() => return +new Date() - lastUpdated >= thirtyMinutes) // only propagate dispatches if time elapsed is 30minutes
      .do(() => lastUpdate = +new Date());
    
    resetIntervalWhenTriggeredManually$
      .flatMap(makeRestCall); // here you insert your rest-call
      .subscribe(
          data => console.log("Data is:", data),
          error => console.error("Error: " + error)
      );
    

    你必须把它放在一个服务中,否则如果视图被销毁,状态就会丢失。

    【讨论】:

    • 谢谢,学到了很多! cmets 很有帮助!该列表将能够从其他页面更新,并且当用户返回列表页面时,它必须在下一次更新之前已经更新。使用 AngularJS 1 我肯定会将所有内容传递给服务,在这种情况下使用 AngularJS 2 我应该遵循相同的逻辑吗?我应该将列表和方法传递给提供者吗?
    • 如果您也在寻找一种 clean 方法来处理 angular2 中的数据和状态,您应该使用 ngrx:github.com/ngrx/store - 有了 ngrx,就有现成的处理数据、更新、数据流等的机制。独立于任何组件,但仍可从组件中控制 - 要获得完整、完美的示例,请查看他们的示例应用程序:github.com/ngrx/example-app - 只需阅读和理解代码,就可以真正从中学到很多东西
    猜你喜欢
    • 2016-06-26
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多