您是否将您的Ionic应用程序升级到v5,而您的应用程序正在使用
Events
,它不再工作?
如果上述情况属实,那么您来对地方了。
先讲个小故事——
几天前,我看到一条来自离子团队的推文,Ionic 5 已发布,在看到该推文 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 一样顺利,但事实并非如此。所以我的转发有点不真实🤗
基本上,对于那个生产 Ionic 应用程序,我在升级到 Ionic 5 和 Angular 9 时遇到了三个问题(我花了一个小时来修复)。为了简洁起见,我将问题和解决方案链接发布到前两个问题:
- TypeScript 编译问题 https://stackoverflow.com/q/60182031/2405040
- Angular AOT 编译问题 https://stackoverflow.com/q/60182031/2405040
-
Events
在 Ionic 5 中删除了它的用法😳
让我们谈谈升级到 Ionic 5 时的第三个重大变化。
如果您看到重大变更,您会看到@ionic/angular
Event 已从 Ionic 5 中删除,他们说要使用Observables
或Redux
作为替代方案。
等等,什么是 Observables 和 redux?😳😱
不用担心,您可以谷歌它并了解它。有大量的博客文章和文章供您实现。但就目前而言,我们必须专注于将我们的应用程序升级到 Ionic 5。
为此,我们将使用 Subject
,它是一种 Obersable
。
但是我不能重构我的代码那么多而且我不知道Observable?
不用担心。Wiz Panda相信#giveback 会帮助支持开源社区。
↓↓↓ 以下代码来自替代 Ionic 5 中删除的事件
因此,让我们首先将以下 Angular 服务复制到您的 Ionic/Angular 代码中,创建一个服务类,你可以使用ionic g service events
命令快速创建一个:
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 发布更改时监听的观察者或回调函数
*
* @returns Subscription 您可以使用变量接收此函数的返回值,然后取消订阅时调用它的`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);
}
/**
* 向给定主题的订阅者发布一些数据
* @param topic 要向其发送数据的主题的名称
* @param data 以任何格式传递的数据
*/
publish(topic: string, data?: any): void {
const subject = this.channels[topic];
if (!subject) {
// 或者您可以为未来的订阅者创建一个新主题
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);
});
基本上,您不能像以前那样获取多个数据。因此,您将在单个参数中获取数据。
d)publish
方法的改变
// 之前
this.events.publish('user:created', someUserInstance, Date.now());
// 之后
this.events.publish('foo:user:logged-out', {
user: someUserInstance,
time: new Date ()
});
因此,之前您可以将多个参数传递给该publish
方法,但现在您必须将它们作为对象传递。
(虽然,您仍然可以调整服务代码以接受相同格式)。
就是这样……
现在,您可以测试您的代码并查看是否一切正常。
快乐编码!
此文翻译自medium博客,
destroy
函数部分更改过(因为ES检查会报错),原文链接:https://medium.com/wizpanda/dealing-with-breaking-change-in-ionic-5-db3ba711dfcd#:~:text=If%20you%20see%20the%20Breaking,or%20Redux%20as%20an%20alternative.