微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

知道何时添加或删除自定义事件?

如何解决知道何时添加或删除自定义事件?

我有一个 Javascript 类 class CheckRazor extends StatefulWidget { const CheckRazor({Key key}) : super(key: key); @override _CheckRazorState createState() => _CheckRazorState(); } class _CheckRazorState extends State<CheckRazor> { Razorpay _razorpay = Razorpay(); var options; Future payData() async { try { _razorpay.open(options); } catch (e) { print(e); } _razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS,_handlePaymentSuccess); _razorpay.on(Razorpay.EVENT_PAYMENT_ERROR,_handlePaymentError); _razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET,_handleExternalWallet); } void _handlePaymentSuccess(PaymentSuccessResponse response) async { print(response); var message = response.paymentId; Navigator.pushReplacementNamed(context,Routes.PaymentSuccess,arguments: widget.details); _razorpay.clear(); } void _handlePaymentError(PaymentFailureResponse response) { var message = response.message; Map res = json.decode(message); Map reason = res["error"]; String finalReason = reason["reason"]; if(finalReason == "payment_cancelled") { Navigator.of(context).pop(context); _razorpay.clear(); } else if(finalReason == "payment_Failed") { Navigator.pushReplacementNamed(context,Routes.PaymentFailure,arguments: response); _razorpay.clear(); } } void _handleExternalWallet(ExternalWalletResponse response) { _razorpay.clear(); } @override void initState() { super.initState(); options = { 'key': // "rzp_test_11111111111",// Enter the Live Key ID generated from the Dashboard "rzp_test_OCp8bDk51p2f96",'amount': 100,'name': 'Test','currency': "INR",'description': 'Fees','prefill': { 'contact': 8888888888,'email': test@email.com,},'external': { 'wallets': ['paytm'] } }; } @override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder( future: payData(),builder: (context,snapshot) { return Container( child: Center( child: Text( "Loading...",style: TextStyle( fontSize: 20,),); }),); } } ,它将创建新事件(例如 Engine),然后在适当的时间分派它们,当间隔过去或它捕获某些事件时,使用 {{1 }}

我有其他类,例如 const event = new Event('build'); 将侦听事件,例如 elem.dispatchEvent(event);。注意:MyButton 不仅仅是一个按钮 - 它是一个类,用于添加按钮、监听按钮和其他事件,并通过点击和其他方式执行各种任务。

主要问题:有没有办法让 elem.addEventListener('build',myListener,false);拦截、捕获或以其他方式知道何时添加删除其事件,以便它可以根据需要启动和停止间隔等?基本上是一个 MyButton 事件,或者一种实现相同效果方法。我可以看到它可以具有用于添加事件侦听器的功能

Engine

但是有没有更好的方法onAddEventListener可以直接调用AddIntervalListener(listener) { // check if the Interval is started,and if not then start it if (this.waitingIntervalId == null) this.waitingIntervalId = setInterval(catchIntervalAndFireEvent,500); // add the event for the caller elem.addEventListener('build',listener,false); } ,并且MyButton知道并且可以根据需要启动Interval?

小问题:addEventListener()页面中的特定元素没有关联。对于Engine 页面中的哪个元素应该用来触发事件,即Engine 中的Engine,是否有最佳实践选择?例如elemelem.addEventListener() 或其他什么? Why do custom events need to be dispatched to an object? 说我必须,但它没有说明使用哪个。或者我应该接受它暗示的建议,并制作自己的事件/侦听器系统?

解决方法

由于您已经在使用自己的按钮实现,只需在那里实现一个 addEventListener() 方法,该方法在调用时引发 customEventAdded 事件:

这是一个例子:

class Engine {
  constructor() {
    this.handleCustomEventAdded = this.handleCustomEventAdded.bind(this); // do this if you need to access the engine instance inside the listener
    document.addEventListener('customEventAdded',this.handleCustomEventAdded);
  }
  handleCustomEventAdded(event) {
    console.log(`Engine learned: a ${event.detail.element.tagName} element was added a listener for ${event.detail.name}`)
  }
}

class MyButton extends HTMLButtonElement {
  addEventListener(event,handler,capture) {
    // pass the method call to HTMLButtonElement.prototype.addEventListener
    super.addEventListener(event,capture);
    console.log(`Eventlistener for ${event} added`);
    switch (event) {
      case 'build':
        let evt = new CustomEvent(
          'customEventAdded',{
            bubbles: true,detail: {
              name: event,element: this
            }
          }
        );
        this.dispatchEvent(evt);
        break;
      default: // noop
    }
  }
}

customElements.define('my-button',MyButton,{
  extends: 'button'
});

new Engine();

document.getElementById('foo').addEventListener('build',function(event) {
  // whatever
})
<button is="my-button" id="foo">My derived button</button>

,

与@connexo 的解决方案相比,这是一个非常简单、不雅的解决方案。尽管如此,它仍然满足我的需求。每种方法都有不同的优点和缺点。我曾希望介于两者之间,例如引擎的订阅者管理改为使用事件,或者其他的东西;如果你有这样的解决方案,请把它放在这里。

class Engine {
    
    intervalTime = 200;
    intervalId = null;
    
    subscribers = [];

    constructor(intervalTime) {
        if (intervalTime!==undefined)
        {   // parameter not omitted in call
            this.intervalTime = intervalTime;
        }

        this.initialise();
    }

    initialise() {
        window.addEventListener("load",this.windowLoadEvent.bind(this));
        this.intervalId = setInterval(this.doInterval.bind(this),this.intervalTime);
    }
    
    // =======================
    
    addSubscriber(subscriber) {
        // note: does not check if subscriber already subscribed
        // could check here if this is the first subscriber and only then start Interval/listening to event
        this.subscribers.push(subscriber);
    }
    
    removeSubscriber(subscriber) {
        // could check here if this is the last subscriber and stop any Interval/listening to event
        this.subscribers = this.subscribers.filter(val => val !== subscriber);
    }

    // =======================
    
    windowLoadEvent() {
        // do stuff
        this.doEvent();
    }
    
    // =======================

    doInterval() {
        for (let i=0; i<this.subscribers.length; i++)
            this.subscribers[i].doRegularInterval();
    }

    doEvent(myVariable) {
        for (let i=0; i<this.subscribers.length; i++)
            this.subscribers[i].doEvent(myVariable);
    }
    
}

class ButtonManager {

    myEngine = null;

    constructor(myEngine) {
        this.myEngine = myEngine;

        this.initialise();
    }


    initialise() {
        myEngine.addSubscriber(this);
    }
    
    // =======================
    
    doInterval() {
        // do stuff
    }
    
    doURLChanged(myVariable) {
        // do stuff
    }
}


let theEngine = new Engine();
let theButton = new ButtonManager(theEngine);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。