0

「ユーザーデータ」という名前のサービスがあります。リクエストを受け取ったときに「ユーザーデータ」をフェッチする責任があります。

「ユーザーデータ」を表示する責任があるページがあります。ページが読み込まれると、データが取得されて表示されます。

いくつかのボタンを含むメニューがあります。これらのボタンをタップすると、サービス「user-data」にリクエストが送信され、データが変更されます。データが変更されたときに、ページが変更について通知され、ページが適応されるようにしたいと考えています。

私がすることは

  • サービス内: "user: change" という名前のイベントを発行し、変更されたデータと共に送信します
クラスUserDataをエクスポート{
    ユーザー = [];
    ....
    //- データが変更された場合、
    //- イベントを発行する
    setUsers(ユーザー) {
        this.users = ユーザー;
        this.events.publish('user:change', users);
    }
}
  • このページで、サブスクライブしてこのイベントをキャッチします
エクスポート クラス UserListPage {
    ユーザー = [];

    //- ページが表示されようとしているときに購読する
    ionViewWillEnter() {
        this.events.subscribe('user:change', this.updateUsers);
    }

    //- ページが表示されようとしているときに購読する
    ionViewDidLeave() {
        this.events.unsubscribe('user:change', this.updateUsers);
    }

    //- アップデート
    updateUsers(userEventData) {

        console.log('アップデートしようとしています');
        if (userEventData[0] instanceof Array) {
             this.users = userEventData[0];
        }
        console.log(this.users);
    }

}

関数updateUsersですべて正常に動作しますが、 this.usersに新しい値が割り当てられていません。とても奇妙です。

時々、デバッグ時に次のようなエラーが発生しました:「読み取り専用プロパティに割り当てようとしました」

なぜなのかご存知ですか?

4

2 に答える 2

3

イベントの代わりにObservablesを使用することをお勧めしますか? イベントでも同じことができますが、データを取得するためにサービスを使用しているため、より良いアプローチになります。ここで、この作業中の plunkerのコードを確認できます。

したがって、通信は次のようになります。

Btn / page ---[call the service]---> Service ---[notify other page and send data]---> Page

したがって、このサービスでは、オブザーバブルを作成して、他のページがそれをサブスクライブし、データの準備ができたときに通知を受けることができます。

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class UserDataService  { 

  private getDataObserver: any;
  public getData: any;

  constructor() {
    this.getDataObserver = null;
    this.getData = Observable.create(observer => {
        this.getDataObserver = observer;
    });
  }

  public getUserData() {
    // Fake data to send to the page
    let userList = [
      { id: 1, name: 'user01 '},
      { id: 2, name: 'user02 '},
      { id: 3, name: 'user03 '}]

    // This simulates an http request
    setTimeout(() => {
      // The next method will notify all the subscribers and will 
      // send the data.
      this.getDataObserver.next(userList);
    }, 1000);
  }
}    

このnext(...)メソッドは、すべてのサブスクライバー (この場合は他のページ) に通知し、データを送信します。

次に、他のページで、データが利用可能になったときに通知されるようにそのオブザーバブルをサブスクライブし、次のようにサービスを呼び出す必要があります。

import { Component } from "@angular/core";
import { UserDataService } from 'service.ts';

@Component({
  templateUrl:"home.html"
})
export class HomePage {

  users: any[];

  constructor(private service: UserDataService) {
      // We subscribe to the observable to be notified when
      // the data is ready
        this.service.getData.subscribe((userList) => {
      this.users = userList;
    });
    }

  public getData(){
    this.service.getUserData();
  }
}

App コンポーネントから配列に を必ず追加してくださいUserDataServiceprovidersこれにより、同じインスタンスがアプリ全体 (シングルトン サービス) で使用されます。

import { Component } from "@angular/core";
import { ionicBootstrap, Platform } from 'ionic-angular/index';
import { HomePage } from './home.ts';
import { UserDataService } from 'service.ts';

@Component({
  template: '<ion-nav [root]="rootPage"></ion-nav>',
  providers: [UserDataService]
})
export class MyApp {
  constructor(private platform: Platform) {
    this.rootPage = HomePage;
  }
}

ionicBootstrap(MyApp);
于 2016-08-09T20:59:53.657 に答える