I have a function SomeFunction(event) -
I want to bind a 'tap' event to a ('#selectorid') element, and I want to know what is the right syntax:
should I use:
$('#selectorid').unbind().bind('tap',SomeFunction);
or:
$('#selectorid').unbind().bind('tap',function(event){
SomeFunction(event);});});
or:
$('#selectorid').unbind().bind('tap',function(){
SomeFunction(event);});
or
$('#selectorid').unbind().bind('tap',SomeFunction(event));
I'm getting completely mixed up about this and would be glad for some clarification..
I'm using the lateset rc2 jquery mobile
#1 should get the job done, but requires that you have "SomeFunction" defined globally:
$( "#selectorid" ).unbind().bind( "tap", SomeFunction );
What will happen is when the event is fired, it will call same "SomeFunction" and pass the event as it's first parameter, So all you have to do is define SomeFunction, like so:
SomeFunction( p_event )
{
// Do cool evil stuff with the event parameter like cancel the tap event >:)
p_event.preventDefault();
// That's it. :)
}
#2 will also work, but again, will require "Somefunction" to be defined globally.
$( "#selectorid" ).unbind().bind( "tap", function(p_event)
{
SomeFunction( p_event );
});
What will happen in the case of #2, is that the anonymous function will call the "SomeFunction" and pass along the event, just like in the first example, but with an extra step. Which is why I prefer the first method. :)
#3 and #4 have errors and are just bad version of the previous two.
Also, what I mean by globally defined, is that the "SomeFunction" is available everywhere on the page, and not just defined in an object, plugin, or closure. Because if it were, then calling it in your event handler may produce undefined errors. If your wondering, I like to use double quotes with my strings and pre-pend my parameter variables with 'p_', so I can use the same variable name in the function, and easily distinguish between the two. It my personal naming convention. :)
Related
I have a third party API that has an event listener adding function which takes as parameter a callback function to be triggered when the event occurs. I would like to pass argument to that callback function. I'm looking for Lua's equivalent of JavaScript's bind.
The Lua code:
EventListenerAddingFunction(myCallbackFunction); // I want to add a param to the callback here
How I would do it in JS:
EventListenerAddingFunction(myCallbackFunction.bind({}, myParameter));
Can this be done in Lua?
No Lua doesn't have this feature, so closest I can think of would be making a closure-wrapper:
EventListenerAddingFunction(function(...) myCallbackFunction({}, myParameter, ...) end)
This passes your parameter everytime the callback is called, all other callback parameters will be passed next. If you don't know your parameters use ... (I don't know them so I used varargs), it's better if you pass exact amount of parameters.
I register callback as event handler in my game, like this:
--register event handler
EventDispatcher:register("fire", mt.onPlayerFire, self)
--this is the event handler
mt:onPlayerFire()
print("play fire")
end
--unregister event handler
EventDispachter:unregister("fire", mt.onPlayerFire, self)
When the event handler is a function in module mt, it is fine to unregister it, because I can find the same function in mt to unregister it, but when I use this form:
EventDispatcher:register("fire", function() doSomething() end, nil)
I could not unregister the event handler, because it is anonymous, so I want to add some checks in my register function to prevent anonymous function as the event handler.
I have found the Proto struct in lua source code may be helpful, but I do not know what each piece means.
https://www.lua.org/source/5.3/lobject.h.html#Proto
I could not unregister the event handler, because it is anonymouse
Every function in Lua is anonymous value. So you can't unregister not because it is anonymous but because you didn't save any reference to it.
There is no way to detect inside of EventDispatcher:register() if the passed value (of function type) is also saved elsewhere. So if you really have multiple callbacks for the same event, and you want to unregister one specific callback, then you must have a way to identify that exact callback function.
That means you should either save the function value somewhere, so its own value could be used later as identifier for unregister(), as it is now, or return new callback's instance id, generated inside of register() when callback was added. Either way, there's something to be stored outside of EventDispatcher to identify exact callback.
This kind of avoids your question a bit, but it might solve your problem nonetheless.
When registering a new callback you could simply return some sort of identifying value, like an ID, a table or even the function itself. This could allow you to unregister it at a later moment.
local firehandler = EventDispatcher:register("fire", function() do('something') end)
-- Do some stuff here...
EventDispatcher:unregister(firehandler)
The downside is that you may have to change the way your event dispatcher keeps track of its registered events, but at worst this means implementing some linked list, and at best you can just use a Lua table to keep track of your handlers.
As for detecting anonymous functions, that's not really possible. Lua doesn't distinguish a function you define in-place from one stored in a variable; it's ultimately the same thing.
It might be possible by using the debug library, by comparing the file/line where a function is defined with the call stack, but that's just inviting bugs into your code and would probably be rather slow.
Here's my attempt:
https://github.com/DaveNotik/dart-stack/commit/99f877491dbd7163aa1bd8d5844c489bdab05eeb
My aim was to make it so when /welcome is detected (which I set the Facebook callback URL to) a window.alert is triggered. But right now it triggers on every page load, so it doesn't seem the router is working appropriately? Is my approach correct?
Most likely you problem is this:
addHandler(Routes.sayWelcome, MainController.sayWelcome(app))
The second argument should be a function to call; but you are calling the function immediately such that its return value is being used as the handler. You need to make this a function so that it will be invoked only when the route is navigated to. For example:
addHandler(Routes.sayWelcome, (_) => MainController.sayWelcome(app))
This seems to be a common issue, however I have one function which seems to work, and another which does not. I get
TypeError:clicked() takes exactly one argument, two given
Where I have binded the clicked function to a Mouse Click.
However, the handler function, which is bound with protocal to the WM_DELETE_WINDOW event, seems to work fine. How are the two different? Thanks!
class GUI():
def __init__(self,root,fit_tuples):
self.fit_tuples=fit_tuples
self.root=root
self.root.title("Beam Flux Registry")
self.root.protocol("WM_DELETE_WINDOW",self.handler)
...
# Calendar Frame
cal=Calendar(LeftFrame)
cal.pack(side=TOP)
cal.bind("<Button-1>",self.clicked)
...
#Mainloop
root.mainloop()
def clicked(self):
print "%i/%i/%i"%(self.cal.selection.month,self.cal.selection.day,self.cal.selection.year)
def handler(self):
self.root.destroy()
self.root.quit()
You need to account for the Event object in the clicked() method. When you bind a widget, the function that handles the binding will receive an object with attributes about the event that fired the function (ie, for a mouse-click event, you'll receive an object with attributes for the cursor's x and y).
The other method works because protocol isn't passing any arguments to the handler.
I'm trying to maintain a widget that triggers events using one of these two lines of code:
this.element.trigger('change'); // or...
stop: function (event, ui) { that.element.change(); }
The word 'change' occurs only 4 times in the code, in one of the 2 forms above. However, I've got no idea what's going on here. There's no event handler in the change call, and there are no bind, delegate, on, or live calls, so something external is presumably setting this up. Can anyone fill me in? Are there any docs on this? Thanks.
Those two lines of code simply trigger a change event to this.element using two different allowed syntax.
Using .trigger():
this.element.trigger('change');
Or using a shorthand method .change():
that.element.change();
You can actually bind an event handler to the element represented by this.element to handle this event.
Without knowing your plugin, it is difficult to answer you precisely on what is this.element.
But take the example of the autocomplete plugin. In this one, this.element is actually the input field the autocomplete plugin is applied to. If the change event was triggered like supposedly done in your question, you could bind an event handler to the input like this:
$('#myinput')
.autocomplete()
.bind('change', function() { });
Now if this plugin relies on the jQuery UI Widget Factory, it is advisable to use the method _trigger() to trigger events instead of the jquery .trigger().
Using _trigger() will make sure to execute any callback defined in the plugin's option with a correct context and also trigger that event for this.element (like above). So you could have:
$('#myinput')
.somePlugin({
change: function(e, someData) {
// "this" here will be `this.element´
}
})
.bind('change', function() { ... });
The answer turned out to be simple - there was no event handler, there were no bind/etc calls, jQuery does nothing behind the scenes, so the trigger calls did nothing. I commented them out and the widget behaved exactly the same. Doh.