首页 文章

Ionic2 StorageModule /更新列表

提问于
浏览
2

离子和角度的新手,我真的很享受它(我终于在javascript中看到了java!)但是在更改后检测数据时遇到了问题 . 我有一个使用离子存储模块保存/检索模拟数据的服务,但是当我使用服务检索我的页面构造函数中的数据时,我的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();
        });
    }    
    }

当我订阅我的页面中的observable时,我的列表将不会更新,直到我与按钮交互 . 我希望在打开页面后立即更新列表 .

@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>

我宁愿使用我的服务然后直接与Storage交互,所以我做错了什么?我也试过不返回一个observable并简单地返回解析的JSON数据,但这也不起作用 .

离子/角度大师,请帮忙!

1 回答

  • 2

    当我订阅我的页面中的observable时,我的列表将不会更新,直到我与按钮交互 . 我希望在打开页面后立即更新列表 .

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

    这是因为一些非常有趣和强大的东西叫 Zones . 如果这个概念对您而言是新的,请参阅herehere以获得惊人的解释 . 你可以在那里看到,

    应用程序状态更改由三件事引起:1)事件 - 用户事件,如点击,更改,输入,提交,... 2)XMLHttpRequests - 例如 . 当从远程服务获取数据Timers - 3)setTimeout(),setInterval()时,因为JavaScript ...事实证明,这是Angular实际上对更新视图感兴趣的唯一情况 .

    因此,您需要让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;
                })
            );
        }    
    }
    

相关问题