處理 Ionic 5 中的重大變化:刪除了Events,如何在ionic 5+版本中實現(xiàn)自定義Events用于舊版本的替代方案?

您是否將您的Ionic應用程序升級到v5,而您的應用程序正在使用Events,它不再工作?

如果上述情況屬實,那么您來對地方了。

先講個小故事——

幾天前,我看到一條來自離子團隊的推文,Ionic 5 已發(fā)布,在看到該推文 10 分鐘后,我僅使用兩個命令將我們的一個中型生產應用程序升級到 Ionic 5 和 Angular 9:

npm install @ionic/angular@latest @ionic/angular-toolkit@latest
ng update @angular/core @angular/cli

運行上述命令后,我驗證了更改,提交了它,然后運行ionic serve但沒有任何效果 ??

我原以為升級到 Ionic 5 會像將普通 Angular 應用程序升級到 Angular 9 一樣順利,但事實并非如此。所以我的轉發(fā)有點不真實??

基本上,對于那個生產 Ionic 應用程序,我在升級到 Ionic 5 和 Angular 9 時遇到了三個問題(我花了一個小時來修復)。為了簡潔起見,我將問題和解決方案鏈接發(fā)布到前兩個問題:

  1. TypeScript 編譯問題 https://stackoverflow.com/q/60182031/2405040
  2. Angular AOT 編譯問題 https://stackoverflow.com/q/60182031/2405040
  3. Events在 Ionic 5 中刪除了它的用法??

讓我們談談升級到 Ionic 5 時的第三個重大變化。

如果您看到重大變更,您會看到@ionic/angular Event 已從 Ionic 5 中刪除,他們說要使用ObservablesRedux作為替代方案。

等等,什么是 Observables 和 redux?????

不用擔心,您可以谷歌它并了解它。有大量的博客文章和文章供您實現(xiàn)。但就目前而言,我們必須專注于將我們的應用程序升級到 Ionic 5。

為此,我們將使用 Subject,它是一種 Obersable。

但是我不能重構我的代碼那么多而且我不知道Observable?

不用擔心。Wiz Panda相信#giveback 會幫助支持開源社區(qū)。


↓↓↓ 以下代碼來自替代 Ionic 5 中刪除的事件

因此,讓我們首先將以下 Angular 服務復制到您的 Ionic/Angular 代碼中,創(chuàng)建一個服務類,你可以使用ionic g service events命令快速創(chuàng)建一個:

import {Injectable} from '@angular/core';
import {Subject, Subscription} from 'rxjs';

/**
 * 自定義事件服務,就像 Ionic 3 事件 https://ionicframework.com/docs/v3/api/util/Events/ 在 Ionic 5 中被刪除。
 *
 * @author Shashank Agrawal
 */
@Injectable({
    providedIn: 'root'
})
export class Events {

    private channels: { [key: string]: Subject<any>; } = {};

    /**
     * 訂閱主題并提供單個處理程序/觀察者
     * @param topic 要訂閱的主題名稱
     * @param observer 發(fā)布更改時監(jiān)聽的觀察者或回調函數(shù)
     *
     * @returns Subscription 您可以使用變量接收此函數(shù)的返回值,然后取消訂閱時調用它的`unsubscribe`方法,以釋放內存資源并防止內存泄漏
     */
    subscribe(topic: string, observer: (_: any) => void): Subscription {
        if (!this.channels[topic]) {
            // 您還可以使用 ReplaySubject 并產生一個結果
            this.channels[topic] = new Subject<any>();
        }
        return this.channels[topic].subscribe(observer);
    }

    /**
     * 向給定主題的訂閱者發(fā)布一些數(shù)據(jù)
     * @param topic 要向其發(fā)送數(shù)據(jù)的主題的名稱
     * @param data 以任何格式傳遞的數(shù)據(jù)
     */
    publish(topic: string, data?: any): void {
        const subject = this.channels[topic];
        if (!subject) {
            // 或者您可以為未來的訂閱者創(chuàng)建一個新主題
            return;
        }
        subject.next(data);
    }

    /**
     * 當您確定您已完成該主題并且訂閱者不再需要收聽特定主題時,您可以使用此方法銷毀該主題的可觀察對象。
     * 銷毀該主題的可觀察對象(這將會在全局銷毀,而不是針對一個可觀察對象)
     * 如果只銷毀一個可觀察對象,在訂閱時用變量接收實例,銷毀時調用實例的 unsubscribe 方法即可
     * @param 要銷毀的主題的名稱
     */
    destroy(topic: string): null {
        const subject = this.channels[topic];
        if (!!subject) {
            subject.complete();
            delete this.channels[topic];
        }
        return null;
    }
}

1. 更改引入

更改之前

import {Events} from 'ionic-angular';

更改之后

import {Events} from '../your/path/to/service/events';

2. 更改subscribe方法

更改之前

events.subscribe('user:created', (user, time) => {
    console.log('Welcome', user, 'at', time);
});

更改之后

this.events.subscribe('user:created', (data: any) => {
    console.log('Welcome', data.user, 'at', data.time);
});

3. 更改publish方法

更改之前

this.events.publish('user:created', someUserInstance, Date.now());

更改之后

this.events.publish('foo:user:logged-out', {
    user: someUserInstance,
    time: new Date()
});

4. 更改Unsubscribe

const subscription = this.events.subscribe('user:foo:created', (data: any) => {
    // your logic
});

完成后,您可以這樣做-

subscription.unsubscribe();

↑↑↑ 以上代碼來自替代 Ionic 5 中刪除的事件


雖然上面已經給出了這些Events步驟,但讓我們運行這些步驟并通過將其與此處給出的原始 Ionic 3 進行比較來快速更改我們的代碼https://ionicframework.com/docs/v3/api/util/Events/

a) 更改導入:

// 之前
import {Events} from 'ionic-angular';
// 之后
import {Events} from '../your/path/to/service/events';

b) 依賴注入沒有變化

constructor(private events: Events) {}

c)subscribe方法的改變

// 之前
events.subscribe('user:created', (user, time) => {
    console.log('Welcome', user, 'at', time);
});
// 之后
this.events.subscribe('user:created', (data: any) => {
    console.log('Welcome', data.user, 'at', data.time);
});

基本上,您不能像以前那樣獲取多個數(shù)據(jù)。因此,您將在單個參數(shù)中獲取數(shù)據(jù)。

d)publish方法的改變

// 之前
this.events.publish('user:created', someUserInstance, Date.now());
// 之后
this.events.publish('foo:user:logged-out', { 
    user: someUserInstance, 
    time: new Date () 
});

因此,之前您可以將多個參數(shù)傳遞給該publish方法,但現(xiàn)在您必須將它們作為對象傳遞。

(雖然,您仍然可以調整服務代碼以接受相同格式)。

就是這樣……

現(xiàn)在,您可以測試您的代碼并查看是否一切正常。

快樂編碼!

此文翻譯自medium博客,destroy函數(shù)部分更改過(因為ES檢查會報錯),原文鏈接:https://medium.com/wizpanda/dealing-with-breaking-change-in-ionic-5-db3ba711dfcd#:~:text=If%20you%20see%20the%20Breaking,or%20Redux%20as%20an%20alternative.

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容