[英]Ionic Events replace with Angular Observables
I understand Ionic events will be deprecated in next version.我了解 Ionic 事件将在下一个版本中被弃用。 Currently I use events to executes functions in my parent page from sub components.
目前,我使用事件从子组件执行父页面中的功能。 Here is an example:
这是一个例子:
In my main page it subscribes to the event to refresh:在我的主页中,它订阅了要刷新的事件:
constructor(){
this.eventFormRefresh = (obj) => {
this.fetch(obj.isReset);
};
this.events.subscribe('form:refresh', this.eventFormRefresh);
}
ngOnDestroy(): void {
this.events.unsubscribe('form:refresh', this.eventFormRefresh);
}
In a subcomponent I activate the refresh by publishing the 'form:refresh' event as so:在子组件中,我通过发布 'form:refresh' 事件来激活刷新,如下所示:
this.events.publish('form:refresh');
How would I do the above using angular observables?我将如何使用 angular observables 执行上述操作?
you can use rxjs Subject for that so first create a common service eg.您可以为此使用rxjs 主题,因此首先创建一个公共服务,例如。
@Injectable()
export class EventService{
private formRefreshAnnouncedSource = new Subject();
formRefreshSource$ = this.formRefreshAnnouncedSource.asObservable();
publishFormRefresh(){
this.formRefreshAnnouncedSource.next()
}
}
then publish like然后像这样发布
this.eventService.publishFormRefresh();
and subscribe in some componenet并订阅一些组件
this.subscription = this.eventService.formRefreshSource$.subscribe(data => {
//do something here
});
and cancel subscription on ngOnDestroy并取消对 ngOnDestroy 的订阅
this.subscription.unsubscribe()
USER EVENTS AS YOU ARE USED TO IN IONIC 3. You just have to import this service/provider in a page you want to use it. IONIC 3 中的用户事件。您只需在要使用的页面中导入此服务/提供者即可。 Reference https://git.furworks.de/opensourcemirror/Ionic/commit/e5f2a18230f3ca3017f0302fb57ef275d0f63a8b
参考https://git.furworks.de/opensourcemirror/Ionic/commit/e5f2a18230f3ca3017f0302fb57ef275d0f63a8b
import { Injectable } from '@angular/core';
export type EventHandler = (...args: any[]) => any;
@Injectable({
providedIn: 'root',
})
export class Events {
private c = new Map<string, EventHandler[]>();
constructor() {
// console.warn(`[DEPRECATION][Events]: The Events provider is deprecated, and it will be removed in the next major release.
// - Use "Observables" for a similar pub/sub architecture: https://angular.io/guide/observables
// - Use "Redux" for advanced state management: https://ngrx.io`);
}
/**
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
*
* @param topic the topic to subscribe to
* @param handler the event handler
*/
subscribe(topic: any, ...handlers: EventHandler[]) {
let topics = this.c.get(topic);
if (!topics) {
this.c.set(topic, topics = []);
}
topics.push(...handlers);
}
/**
* Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
*
* @param topic the topic to unsubscribe from
* @param handler the event handler
*
* @return true if a handler was removed
*/
unsubscribe(topic: string, handler?: EventHandler): boolean {
if (!handler) {
return this.c.delete(topic);
}
const topics = this.c.get(topic);
if (!topics) {
return false;
}
// We need to find and remove a specific handler
const index = topics.indexOf(handler);
if (index < 0) {
// Wasn't found, wasn't removed
return false;
}
topics.splice(index, 1);
if (topics.length === 0) {
this.c.delete(topic);
}
return true;
}
/**
* Publish an event to the given topic.
*
* @param topic the topic to publish to
* @param eventData the data to send as the event
*/
publish(topic: string, ...args: any[]): any[] | null {
const topics = this.c.get(topic);
if (!topics) {
return null;
}
return topics.map(handler => {
try {
return handler(...args);
} catch (e) {
console.error(e);
return null;
}
});
}
}
// make service using: ionic g service events // 使用: ionic g 服务事件创建服务
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class EventsService {
private refreshData=new Subject();
constructor() {};
refreshData= this.refreshDatasObservable();
refresh(message){
this.refreshDatanext(message)
}
}
in app.module.ts在 app.module.ts
import {EventsService} from './service/vents.service'; // add it to provider
providers:[....
EventsService
....
]
in your desired page subscribe and call like this在您想要的页面中订阅并像这样调用
import {EventsService} from './service/vents.service'; //import service
constructor(private eventsService:EventsService){
//for refreshing or publishing
this.eventsService.refresh('i am data');
//for subscribing to change
this.eventsService.refreshChatData$.subscribe(data=>{
//do something
})
}
You can create a service with a BehaviorSubject
and you can pass data and subscribe to it wherever you want.您可以使用
BehaviorSubject
创建服务,并且可以传递数据并在任何您想要的地方订阅它。 In your case pass in the child and subscribe in the parent component.在您的情况下,传入子组件并订阅父组件。
For anyone else finding this in the same setup I was in, here's another possible route.对于在与我相同的设置中发现此问题的其他人,这是另一种可能的路线。 We're looking at going from Ionic V3 -> V4 and know we have some headaches in store.
我们正在考虑从 Ionic V3 -> V4 开始,并且知道我们有一些令人头疼的问题。 One being events deprecated.
一个是不推荐使用的事件。 I decided to look how the ionic-angular implementation of events was set up, and realized I kind of liked it.
我决定看看事件的离子角度实现是如何设置的,并意识到我有点喜欢它。 I made a service mimicking their implementation, hoping that replacing the ionic-angular Events later will be easier.
我做了一个模仿他们实现的服务,希望以后替换离子角事件会更容易。
@Injectable()
export class Events {
private _channels: { [key: string]: ((...args: any[]) => void)[] } = {};
public subscribe(topic: string, handler: (...args: any[]) => void) {
if (!this._channels[topic]) {
this._channels[topic] = [];
}
this._channels[topic].push(handler);
}
public publish(topic: string, ...args: any[]) {
if (this._channels[topic] && this._channels[topic].length) {
this._channels[topic].forEach(handler => handler(...args));
}
}
public unsubscribe(topic: string, handler: ((...args: any[]) => void) = null) {
if (!handler) {
delete this._channels[topic];
}
const index = this._channels[topic].indexOf(handler);
if (index > 0) {
this._channels[topic].splice(index, 1);
}
if (!this._channels[topic].length) {
delete this._channels[topic];
}
}
}
I know this doesn't use Observables, but wanted to offer a different solution for anyone else hoping for a drop-in fix for ionic-angular/events I simplified / removed some of their code, if there's any concerns let me know.我知道这不使用 Observables,但想为其他任何人提供不同的解决方案,希望为我简化/删除了他们的一些代码的 ionic-angular/events 提供直接修复,如果有任何问题请告诉我。
This can be dealt with by using an Events service as pointed out in this medium post Dealing with breaking change in Ionic 5这可以通过使用事件服务来处理,正如这篇中篇文章处理 Ionic 5 中的重大变化中所指出的那样
The author illustrates how one can refactor code with minimal ease and maintain the flow.作者说明了如何以最简单的方式重构代码并保持流程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.