问题描述
我有一个 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
,是否有最佳实践选择?例如elem
或elem.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);