Ionic2 StorageModule/Updating 列表

Ionic2 StorageModule/Updating List

ionic 和 angular 的新手,我真的很喜欢它(我终于在 java 脚本中看到了 java!)但是我在检测数据时遇到了问题改变之后。 我有一个使用离子存储模块 saves/retrieves 模拟数据的服务,但是当我使用该服务在我的页面构造函数中检索数据时,我的 HTML 没有改变。

    import { Component, Injectable } from '@angular/core';
    import { Storage } from '@ionic/storage';
    import {Observable} from 'rxjs/Observable';

    @Injectable()
    export class IconService{

        private allNotifications:Notification[] = [];

        constructor(private storage:Storage) { 
            storage.ready().then(() => {});
        }

    public getAllNotifications(){
        this.storage.get('allNotifications').then((data)=>{
                this.allNotifications = JSON.parse(data);
        });
        return Observable.create(observer => {
            observer.next(this.allNotifications);
            observer.complete();
        });
    }    
    }

当我订阅页面中的可观察对象时,我的列表只有在我与按钮交互后才会更新。我希望在打开页面后立即更新列表。

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {
constructor(public navCtrl: NavController, public navParams:NavParams, public modalCtrl:ModalController,
    private iconService:IconService,private storage:Storage) {
    this.iconService.getAllNotifications().subscribe(data =>this.notifications = data);
  }

  ionViewWillEnter(){
    this.iconService.getAllNotifications().subscribe(data =>this.notifications = data);
  }
  }

但是,当我从我的页面调用 storage.get()

constructor(public navCtrl: NavController, public navParams:NavParams, public modalCtrl:ModalController,
    private iconService:IconService,private storage:Storage) {
    this.storage.get('allNotifications').then((data)=>{
                this.notifications = JSON.parse(data);
        });
  }

数据已加载,页面打开后 html 会立即更新。如果需要,这是 html:

<div *ngIf='notifications'>
   <button ion-fab *ngFor='let notification of notifications' [color]="day ? 'light' : 'moon'"><ion-icon name='{{notification.icon}}'></ion-icon></button>
</div>

我宁愿使用我的服务,也不愿直接与存储交互,那么我做错了什么?我也试过不返回可观察对象,只是返回解析后的 JSON 数据,但这也不起作用。

Ionic/Angular请各位大侠帮忙!

When I subscribe to the observable in my page, my list won't update until I interact with a button. I want the list to be updated as soon as the page is opened.

这似乎是一个与 Angular 相关的问题,因为它不知道您在服务中做了什么,所以它不知道它应该更新视图。这也将解释为什么当您与按钮交互时视图会更新。

那是因为一个非常有趣和强大的东西叫做 Zones。如果这个概念对您来说是新的,请参阅 here and here 以获得精彩的解释。如您所见,

Application state change is caused by three things:

1) Events - User events like click, change, input, submit, …

2) XMLHttpRequests - E.g. when fetching data from a remote service Timers -

3) setTimeout(),setInterval(), because JavaScript

it turns out that these are the only cases when Angular is actually interested in updating the view.

因此您需要让 Angular 知道某些内容已更改并且需要我们了解更新内容。我们可以尝试像这样更改您的代码:

import { ..., NgZone } from '@angular/core';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {

    constructor(public navCtrl: NavController, 
                public navParams: NavParams, 
                public modalCtrl: ModalController,
                private iconService: IconService,
                private storage: Storage,
                private ngZone: NgZone) {

        // Subscribe only here, no need for doing it also in ionViewWillEnter
        this.iconService.getAllNotifications().subscribe(
            data => {
                this.ngZone.run(() => {
                    // Now Angular knows that something has changed, 
                    // and the view needs to be checked/updated
                    this.notifications = data
                });            
            });
    }

}

您还可以使用 Observable.fromPromise 运算符简化服务代码:

import { Component, Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class IconService {

    private allNotifications: Notification[] = [];

    constructor(private storage:Storage) { }

    public getAllNotifications(): Observable<any> {

        return Observable.fromPromise(
            this.storage.get('allNotifications').then(data => {

                // Update the data
                this.allNotifications = JSON.parse(data);

                // Return the data to the caller
                return this.allNotifications;
            })
        );
    }    
}