简体   繁体   English

如何从ionic2中的服务更新页面?

[英]How to update the page from the service in ionic2?

I have a service named "user-data", it is responsible to fetch the "user data" when it receives a request. 我有一个名为“用户数据”的服务,它负责在收到请求时提取“用户数据”。

I have a page which is responsible to show the "user data". 我有一个页面负责显示“用户数据”。 When the page is loaded, it gets data and show. 页面加载后,它会获取数据并显示。

I have a menu, which contains some buttons. 我有一个菜单,其中包含一些按钮。 Tapping on these button will send a request to the service "user-data" and modify the data. 轻触这些按钮将向服务“用户数据”发送请求并修改数据。 When the data is modified, I want to the page gets notified about the change and adapts the page. 修改数据后,我希望页面收到有关更改的通知并调整页面。

What I do is 我要做的是

  • In the service: publish an event named "user: change", and send with the modified data 在服务中:发布一个名为“用户:更改”的事件,并发送修改后的数据
export class UserData{
    users = [];
    ....
    //- if data is changed, 
    //- publish an event
    setUsers(users) {
        this.users = users;
        this.events.publish('user:change', users);
    }
}
  • In the page, subscribe to catch this event 在页面中,订阅以捕获此事件
export class UserListPage {
    users = [];

    //- subscribe when the page is about to show
    ionViewWillEnter() {
        this.events.subscribe('user:change', this.updateUsers);
    }

    //- subscribe when the page is about to show
    ionViewDidLeave() {
        this.events.unsubscribe('user:change', this.updateUsers);
    }

    //- update
    updateUsers(userEventData) {

        console.log('About to update');
        if (userEventData[0] instanceof Array) {
             this.users = userEventData[0];
        }
        console.log(this.users);
    }

}

Everything works fine in the function updateUsers , except this.users is not assigned the new value. updateUsers函数中,一切正常,除了this.users没有分配新值。 It's very strange. 真奇怪

Sometimes, when I debug, I got an error like : "attempted to assign to readonly property" 有时,当我进行调试时,出现类似“尝试分配给只读属性的错误”的错误信息

Do you know why? 你知道为什么吗?

May I suggest using Observables instead of events? 我可以建议使用Observables代替事件吗? Even though you can accomplish the same with events, since you're using a service to get the data, it would be a better approach. 即使您可以通过事件来完成相同操作,但是由于您正在使用服务来获取数据,因此这将是更好的方法。 Here you can see the code in this working plunker . 在这里,您可以看到此工作插件中的代码。

So the communication will be: 因此,通信将是:

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

So in the service, you can create an observable, so other pages can subscribe to it, and be notified when the data is ready. 因此,在该服务中,您可以创建一个可观察的对象,以便其他页面可以订阅它,并在数据准备好时得到通知。

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);
  }
}    

The next(...) method will notify to all the subscribers (the other page in this case) and will send it the data. next(...)方法将通知所有订户(在这种情况下为另一页),并将数据发送给该订户。

Then in the other page you just need to subscribe to that observable to be notified when the data is available and call the service like this: 然后,在另一页面中,您只需要订阅该可观察对象,以便在数据可用时得到通知,并像这样调用服务:

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();
  }
}

Make sure to add the UserDataService in the providers array from the App component, so the same instance will be use in the entire app (singleton service). 确保在App组件的providers数组中添加UserDataService ,以便在整个应用程序(单个服务)中使用相同的实例。

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);

The only thing I am wrong is to write the function to handle "updateUser" in a separate place. 我唯一的错是在单独的地方编写处理“ updateUser”的函数。 The following code works for me: 以下代码对我有用:

<pre>
export class UserListPage {
    users = [];

    //- subscribe when the page is about to show
    ionViewWillEnter() {
        this.events.subscribe('user:change', (userEventData){
            console.log('About to update');
            if (userEventData[0] instanceof Array) {
                  this.users = userEventData[0];
            }
            console.log(this.users);
        );
    }

    //- subscribe when the page is about to leave
    ionViewDidLeave() {
        this.events.unsubscribe('user:change', ()=>());
    }

}
</pre>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM