簡體   English   中英

如何在Ionic2的彈出視圖中重置注入的對象?

[英]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,然后如果發現整個對象都將被覆蓋。

SyncService類:

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

    }

子頁面(AssetPage):

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

}

父頁面(ParkPage)構造函數:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM