2017-07-31 2 views
6

私はイオン2アプリを持っています。アプリの前提は、クラスを取ることです。クラスが開かれると、ユーザーはリモートAPIでこのクラスを取るとマークされます。Ionic 2のルートページにデータを戻すにはどうしたらいいですか?

データの流れは以下のとおりです。

  1. ユーザーが「クラス]タブを開きます。
  2. APIからのアプリケーション要求 'クラス'データ。各クラスはそのユーザーの「ステータス」を保持します。
  3. ユーザーがクラスを選択します。これは、NavController.push(Page, { 'classes': classObjFromApi });を使用してアプリで新しいビューを開きます。
  4. スタックにいくつかのページが追加され、それぞれにclassesオブジェクトが渡されます。
  5. 最後のページで
  6. APIは、現在のクラスが撮影されていると、ユーザは、各クラスのルートページでNavController.popToRoot()

を使用して戻ってルートにナビゲートできることを知らされるのステータスが示されている( 『』未開始、 '進行中'、 '完了済み')。上記のフローのポイント5では、ユーザーはルートに戻されますが、これは最初に作成されたときからのデータを持ち、「完了」していても「開始していません」というクラスを示しています。

スタックの別のページからルートページのデータを更新するにはどうすればよいですか?私はpopToRoot()navParamsを受け入れると仮定していたので、ルートページにそのデータが存在するかどうかを確認し、存在する場合はそれを使用し、存在しない場合はAPIから要求します。

ionViewDidEnterメソッドでAPIからデータを再リクエストすることでこの問題を回避することができますが、このページが表示されるたびにAPIにHTTPリクエストがあることを意味します。面倒です。

データを表示する前にデータをストレージから取得するまで待つ必要があるため、ページを読み込むときに遅延が発生するため、内部のストレージを使用しないでください。

私の質問:これを行う最善の方法は何ですか?データをビューに渡す場合は、popToRoot()がnavパラメータをサポートしていない場合はどうすればよいですか?

答えて

8

それを行うための最善の方法は、Eventsを使用して次のようになります。あなたのルートページで

、いくつかのコードにそのイベントが公開されるたびに実行するために、カスタムイベントをサブスクライブ:

import { Events } from 'ionic-angular'; 

constructor(public events: Events) { 
    events.subscribe('status:updated', (updatedData) => { 
    // You can use the updatedData to update the view 
    // ... 
    }); 
} 

// Clean up the subscription when the page is about to be destroyed 
ionViewWillUnload() { 
    this.events.unsubscribe('status:updated'); 
} 

そして、ユーザがそのデータを変更したときに、他のページにそのイベントを公開:

import { Events } from 'ionic-angular'; 

constructor(public events: Events) {} 

yourMethod(): void { 
    // Your custom logic... 
    // ... 

    // Now you can publish the event to update the root page (and any other page subscribed to this event) 
    this.events.publish('status:updated', updatedData); 
} 

EDIT

それを行う別の方法は、共有サービスを使用して、変更をパブリッシュ/サブスクライブするSubjectを使用することによりだろう。結果はのイオンイベントのと非常に似ていますが、このシナリオでは共有サービスを追加し、データが更新されるときにそれを使用する必要があります。私はイオンのイベントを好むだろうが、念のために、これはあなたがそれを行うことができる方法である:

import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class MySharedService { 
    public onDataChange: Subject<any>; 

    constructor() { 
    this.onDataChange = new Subject<any>(); 
    } 

    public publishUpdate(newData): void { 
    // Send the data to all the subscribers 
    this.onDataChange.next(newData); 
    } 
} 

だから今、あなたのルートページでは、共有サービス

import { Subscription } from 'rxjs/Subscription'; 

// ... 

private onDataChangeSubscription: Subscription; 

constructor(public mySharedService: MySharedService) { 
    this.onDataChangeSubscription = mySharedService.onDataChange.subscribe(
    updatedData => { 
     // You can use the updatedData to update the view 
     // ... 
    }); 
} 

// Clean up the subscription when the page is about to be destroyed 
ionViewWillUnload() { 
    this.onDataChangeSubscription.unsubscribe(); 
} 

を使用して変更を購読し、あなたは他のページからのデータを更新する際、あまりにも共有サービスを使用する必要があるだろう:

constructor(public mySharedService: MySharedService) {} 

yourMethod(): void { 
    // Your custom logic... 
    // ... 

    // Now you can publish the event to update the root page (and any other page subscribed to this event) 
    this.mySharedService.publishUpdate(updatedData); 
} 

あなたには、いくつかのカスタムロジックにデータが更新されるたびに実行する必要がある場合は、このアプローチはそうdの代わり、良いかもしれません各サブスクライバは、共有サービスでそれを実行し、結果をブロードキャストすることができます。

+1

+1イベントの使用を推奨するために+1 - リスナーの数が多いとアプリケーションの速度が低下することがありますが、非常に便利な機能! –

+1

素晴らしいです、これは私が探していたものです。単一のイベントリスナーは、このインスタンスで1トンのAPI呼び出しを節約します。 – Mike

+1

それを聞いてうれしい!私は、あなたがプロセスをよりコントロールする必要がある場合に備えて、そのための別の方法を追加する答えを編集しました。しかし、Ionic Eventsとはかなり似ていますので、最初のアプローチはあなたのシナリオでは十分すぎると思います。 – sebaferreras

関連する問題