[英]How to reset injected object at view pop in Ionic2?
我正在嘗試執行以下操作:
我有一個這樣的對象:
let demo_obj = {
park_name: "Park #01",
assets:
[
{
id: 1,
name: "Test #01"
},
{
id: 2,
name: "Test #02"
},
{
id: 3,
name: "Test #03"
}
],
}
頁面通過*ngFor
循環瀏覽資產對象,將每個資產列為列表項。
<ion-list>
<ion-item *ngFor="let asset of demo_obj.assets" (click)="gotoAsset(asset)">
<ion-avatar item-left>
<img [src]="asset.cover_image_public_path">
</ion-avatar>
<h2>{{asset.nome}}</h2>
</ion-item>
</ion-list>
當用戶單擊按鈕時,將執行以下代碼:
gotoAsset(asset) {
this.navCtrl.push(AssetPage, { asset: asset });
}
這將推動顯示資產詳細信息的頁面。
當新頁面進入堆棧時,它將從導航參數中獲取資產,並對其進行備份以將其字符串化。
ngOnInit() {
this.asset = this.navParams.get("asset");
this.original_asset = JSON.stringify(this.asset);
}
此處的用戶可以更改資產的多個屬性。 但是,當他嘗試不保存更改而返回時,應用程序會向用戶發出確認警報,如果他確定要退出丟失的更改:
ionViewCanLeave(): boolean {
if (JSON.stringify(this.asset) === this.original_asset) {
return true;
}
if (this.can_go_back) {
return true;
}
this.askForLeaveConfirmation();
return false;
}
private askForLeaveConfirmation() {
let confirm = this.alertCtrl.create({
title: 'Do you confirm?',
message: 'Leaving the page without saving, will reset the resource at its original state. Are you sure?',
buttons: [
{
text: 'Disagree',
handler: () => {
console.log('Disagree clicked');
}
},
{
text: 'Agree',
handler: () => {
this.asset = JSON.parse(this.original_asset);
this.can_go_back = true;
this.navCtrl.pop();
console.log('Agree clicked');
}
}
]
});
confirm.present();
}
此時,如果他選擇“同意”,則資源將被重置。 一切正常,實際上,您可以在動畫開始之前的很短時間內看到資源被重置。
當this.navCtrl.pop()
被調用時,發生了奇怪的事情。 即使重置了資源,上一頁也會保留更改。
我以為它與上一頁有某種聯系,因為我在頁面之間不斷傳遞相同的對象。 我在哪里做錯了?
我設法解決了一個問題。
創建一個名為SyncService的服務,該服務將注意備份給定的對象並提供其副本。
然后可以使用適當的方法取回該副本。
保留對象的備份副本使我可以對ionViewCanLeave()
方法和父頁面的構造方法進行檢查。
核心密鑰是使用事件。 當用戶確認警報中對象的重置時,將發布事件,並且父頁面的構造函數將訂閱該事件。
在訂閱中,我們將循環所有當前資產以搜索相同的ID,然后如果發現整個對象都將被覆蓋。
import { Injectable } from "@angular/core";
@Injectable()
export class SyncService {
public resource;
public workOnCopy(resource: any, res_type: string): boolean {
sessionStorage.setItem("astrid_mobile_tmp_" + res_type + "_bak", JSON.stringify(resource));
this.resource = resource;
return this.resource;
}
public getBackedUpResource(res_type: string, parse: boolean = true): any {
let res = sessionStorage.getItem("astrid_mobile_tmp_" + res_type + "_bak");
if (!res) {
return false;
}
if (parse) {
JSON.parse(res);
}
return res;
}
}
@Component({
selector: 'page-asset',
templateUrl: 'asset.html'
})
export class AssetPage implements OnInit {
public asset;
private can_go_back: boolean = false;
constructor(
private navCtrl: NavController,
private navParams: NavParams,
private alertCtrl: AlertController,
private Events: Events,
private SyncService: SyncService,
) {
this.asset = this.SyncService.workOnCopy(this.navParams.get("asset"), "asset");
}
ionViewCanLeave(): boolean {
if (JSON.stringify(this.asset) === this.SyncService.getBackedUpResource("asset")) {
return true;
}
if (this.can_go_back) {
return true;
}
this.askForLeaveConfirmation();
return false;
}
private askForLeaveConfirmation() {
let confirm = this.alertCtrl.create({
title: 'Do you confirm?',
message: 'Leaving the page without saving, will reset the resource at its original state. Are you sure?',
buttons: [
{
text: 'Disagree',
handler: () => {
console.log('Disagree clicked');
}
},
{
text: 'Agree',
handler: () => {
console.log("Event fired");
this.Events.publish("asset:reseted", this.SyncService.getBackedUpResource("asset"));
this.can_go_back = true;
this.navCtrl.pop();
console.log('Agree clicked');
}
}
]
});
confirm.present();
}
}
constructor(
private navCtrl: NavController,
private navParams: NavParams,
private Events: Events,
) {
this.park = this.navParams.get("park");
this.Events.subscribe("asset:reseted", (bak_asset) => {
let asset = JSON.parse(bak_asset);
for (let i = 0; i < this.park.assets.length; i++) {
if (this.park.assets[i].id == asset.id) {
this.park.assets[i] = asset;
}
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.