刚接触 ionic 和 Angular,我真的很喜欢它(我终于在 javascript 中看到了 java!),但是我在检测数据更改后遇到了问题。 我有一个使用 ionic 存储模块保存/检索模拟数据的服务,但是当我使用该服务检索页面构造函数中的数据时,我的 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 不知道您在服务中做什么有关的问题,因此它不知道应该更新 View 。这也将解释为什么当您与按钮交互时 View 会更新。
那是因为有一个非常有趣且强大的东西,称为区域。如果这个概念对您来说是新的,请参阅here和 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;
})
);
}
}
关于angular - Ionic2 StorageModule/更新列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45473616/