无法使用Ionic 5侦听发出的事件

r8uurelv  于 2022-12-08  发布在  Ionic
关注(0)|答案(3)|浏览(178)

I created a simple ionic app that allows users to book services. The user would select a service category, choose a service(s) then navigate to a form to complete the booking.
I've setup an event bus using tiny emitter since the project uses vue 3 with the composition api. The data emits as expected however when navigating to the booking form the listener is not triggered.
The expected behaviour is to get the selected service(s) and send it along with the rest of the booking info to a REST api.

eventBus.js

import { TinyEmitter } from 'tiny-emitter';
const emitter = new TinyEmitter();
const eventBus = () => {
    return { emitter };
};
export default eventBus;

Service.vue

// template

<ion-button routerDirection="forward" routerLink="/booking" @click="sendEvent">Book Now</ion-button>

// script

import eventBus from './eventBus';

export default {
  ...
  setup() {
    ...
    const sendEvent = () => {
      eventBus().emitter.emit('selected-service', 100) // the real code emits an array
    }
    return { sendEvent }
  }

}

Booking.vue - Nothing happens in the console log

<script>
...
onMounted(() => {
  eventBus().emitter.on('selected-service', (payload) => {
    console.log('listener', payload);
  })
})
</script>

I know this works in a regular Vue 3 project but I'm not sure why it's not working with ionic.

Things I've tried

  • Using the native emitter via context as a setup param. https://v3.vuejs.org/guide/composition-api-setup.html#accessing-component-properties
  • Using the mitt package as described here: Vue 3 Event Bus with Composition API
  • Emitting the event when the user chooses a service rather than when they click "Book Now"
  • Calling the listener in setup() directly rather than onMounted.
    UPDATE

I noticed the listener gets called when I navigate off the booking page then back to it. So if I go from service details -> booking -> back to service details -> booking it triggers the bus and the payload is captured.

wpx232ag

wpx232ag1#

这可能是一个框架级的bug。我已经通过twitter和Ionic团队谈过了,他们建议我使用查询参数来代替,所以这就是我采取的路线。

monwx1rj

monwx1rj2#

也许rxjs能帮你

import { Subject } from 'rxjs';
private newProduct = new Subject<any>();

publishNewProduct() {
 this.newProduct.next();
}

subscribeNewProduct(): Subject<any> {
 return this.newProduct;
}
axr492tv

axr492tv3#

我也遇到了同样的问题,更糟糕的是,在我的情况下,bug是间歇性的,只有在开发工具控制台关闭时才会出现。打开开发工具或使用警报会导致组件及时呈现以接收事件..我几乎为此失去了理智。
在我的例子中,使用immediate: true在a prop上使用watcher是最干净的解决方案。
我认为这个错误是 * 真的 * 讨厌,因为全局事件支持已从Vue2和Vue3升级文档明确建议使用微型发射器来实现它。
这会导致怪异的行为和几乎无法追溯的bug,出于这个原因,我认为应该尽可能避免全局事件模式。
作为最后一点说明,如果它能帮助某些人,这就是我最终能够使用控制台日志将问题追溯到全局事件总线的原因:

const logs = []
app.config.globalProperties.$log = function () { logs.push(arguments) }
window.viewlogs = () => {
  for (let i = 0; i < logs.length; i++) {
    console.log.apply(window, logs[i])
  }
}

一旦出现错误,我就可以打开开发工具并使用window.viewlogs()查看日志

相关问题