Say I have a variable "stateName," (or rather a className in my exact case) and every time the value of stateName changes, which might be for any of myriad reasons, I want the program to respond in a uniform way.
I am thinking that I want to create an event "stateChanged" and an eventListener that listens for this change and executes a function accordingly?
I don't really know how to make custom events in javascript though, and I also don't know if this is a good approach. Any suggestions?
use a setter function so you never manipulate it directly, and then you can generate a custom event for it. If it has to trigger even when "something else" changes the value, you need to use something more powerful like mutation observing
Related
I'm playing a bit with Backbone.js and Backbone.Marionette and I would like to know what's the difference between trigger and triggerMethod.
In particular, is there any rule of thumb to decide when use the former or the latter?
In my mind events, for example, are useful to communicate between a DOM element and its view.
triggerMethod is used in Marionette to update in cascade different components, e.g. a layout calls the show method to its children (children respond to onShow). So, for me its the same as calling a direct method on it. Is this true?
What about trigger?
Thanks you in advance.
There isn't a huge difference, and it simply depends on what you want to do...
trigger will trigger an event
triggerMethod will trigger an event AND call a corresponding method according to naming convention (see https://marionettejs.com/docs/v2.1.0/marionette.functions.html#marionettetriggermethod)
Obviously, if you only want to trigger an event, you'd use trigger. But using trigger you also create a "home made" triggerMethod implementation: trigger the event, then have a listener that will call the function you want.
So what about triggerMethod ? As mentioned above, it will trigger an event and call a method. So if your only objective is to call the method in the first place, there isn't necessarily a need for using triggerMethod.
So why would one use triggerMethod at all? Because it gives you "hooks" to add functionality with event listeners. In my book on Marionette, for example, there is a triggerMethod call in https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/edit/edit_controller.js#L24 to display error messages on a form. The same could be achieved by simply calling
view.onFormDataInvalid(contact.validationError);
But as mentioned above, triggerMethod give us a "hook" for later use. For example, let's say I want to add logging of user errors: I can simply add a listener to my view:
initialize: function(){
this.on("form:data:invalid", function(validationError){
// log error here
}
}
This additonal functionality can be added without impacting the rest of the code, because we've used triggerMethod instead of a direct method call. In addition, it will be easier to test later (small tests, with single point of failure):
test that "form:data:invalid" event is triggered when a user enters incorrect info
test that when "form:data:invalid" event is triggered, error gets logged
etc.
trigger(name)
Part of Backbone.js
Triggers event using the name passed in
triggerMethod(name)
Part of Marionnete.js
Does everything trigger(name) does
Also calls methods using a predefined naming convention.
eg. triggerMethod('foo') will call onFoo()
eg. triggerMethod('foo:bar') will call onFooBar()
Other javascript is changing the value of an input and I was wondering if there was a way to detect the change.
This question has nothing to do with Keyup or Change. This is not being typed in by the user it is being changed by other javascript though various actions of the user.
When changing an event programatically, you can trigger a change event to make sure event handlers that are attached to the element are fired. jQuery has a trigger() method to do this:
$('#elementID').on('change', function() {
alert( this.value );
});
$('#elementID').val('some new value').trigger('change');
The quick run-down of what I am going to say is: there is no way other than to modify the third-party scripts to output stuff, or to use setInterval (costly).
The bottom line of this issue is a simple one, that does not appear to be so at first: How can you get your scrips to communicate with each other?
When a script modifies the value of an input through JS methods (i.e. not user input), they have to go through specific hoops to get the "change" event to fire (they can fire it manually by calling it, which most devs never do and is easily forgotten when writing code). In practice, people tend to rely on the observation events (user-defined ones) to track code changes. This is very similar to DOM events - you bind callbacks to your script, which allow you to tap callbacks in that will fire whenever your scripts do something interesting (like modifying inputs. This is just one example). You then teach your scripts and developers to fire events on useful stuff using the callbacks to notify other scripts.
A great library for this is Postal, which is originally a Node library. jQuery also has an event system you can tap into. However, if you want to roll your own, all you have to read into is the Observer design pattern. It is trivial: you bind a function to your object to pick up callbacks, and another to fire them. Whenever you change the thing, you fire the callback. Simples.
Failure to do so means setInterval. Sucks, but there you go :-(
I see other questions for how to create custom events, but I'm not clear on how to track specific custom conditions.
In my example, I need to "listen" for the eventuality that an array has gone from having x elements to y elements.
I'm not sure if it's a good idea to prototype on top of Array, though that's kind of ideally what I need.
However, the broader question is, what's the methodology for writing custom listeners that are effectively the analog of -pseudo-
onClockStruckTwo
or
onDomChanged
or
onRapture
Meaning, that rather than waiting for some other predefined onEvent (onclick, onkeydown, etc) to happen, I want to make my own.
And please no Framework answers. I'm trying to understand how this actually works in native javascript.
TIA
The question I ask you is "what are you listening from?" If you're listening to a change on the server you could setTimeout an AJAX call, but that'd be far from suggested. If you're strictly looking to have the length of an element change, then there must be something else that you can know will set off the event. I say if it's not server related, don't "listen" at all, just attach the desired Javascript code to the end of something that you know will trigger the event change.
EDIT
Here's a list of all the Javascript event types. I don't see any mentions of an DOM object being empty. You may SOL with the way your hoping to do it.
Arrays do not have any sort of event notification system for changes in javascript. So, if you wanted to know when an array was changed, you would have to create your own notification system.
Since you don't want to use any frameworks (many of which offer event notification and triggering things), you would have to build your own.
There are several different approaches for event systems (messages through a generic message callback, individual callbacks for each event, object oriented approaches of either of these, etc...
The most straightforward (thought not necessarily the most elegant) is to have the object that creates the event maintain a list of callbacks for the event. Then, when an interested party wants to register for the event, they call a method and pass it the event and a callback. This is similar to how addEventListener works in the browser DOM for DOM events. The recipient of that method call, then stores the callback in an array of callbacks. Some time later when the actual event occurs, each callback that is registered for that event is called in turn.
Since array modifications don't trigger events by themselves, you would have to implement a function that both makes the array change and signals the event.
So I am very new to Box2D and I'm trying to figure out how to use b2ContactListener.
Are you allowed to set more than one Contact Listeners to a world? I would think so. But when set two contact listeners like so:
world.SetContactListener(listener);
world.SetContactListener(listener2);
It behaves like listener2 was the only one set. Why is that?
Also when I change the order of how I set the listeners like so:
world.SetContactListener(listener2);
world.SetContactListener(listener);
Then it behaves like listener was the only contact listener set and ignores listener2.
The only reason I think why this could be behaving like this is because both of the listeners override the BeginContact and EndContact methods so it's confused.
I am using the JavaScript port of Box2D (Box2DWeb) by the way. But if you know the solution to the issue in Objective-C or C++ that's fine as I know those languages.
The hint is in the name - "Set" rather than "Add". It implies that there is only 1 listener supported. Update your listener class to dispatch to multiple methods if you need to.
It seems you are confused about what overriding methods entails. Having the same method overridden on multiple objects does not cause anything to get confused. The issue is that there is only one listener meant to be registered at once (because having a lot of listeners would slow things down - it will get called a lot)
I'm trying to get my head around custom events. I understand how to register and trigger custom events. However, it seems like its not possible to register truly custom events. Everything has to trace back to a DOM event like click, onload, blur, etc. Or am I wrong?
For example, suppose I have an array. I want to register an event that fires when the length of the array changes. To my understanding, I would have to register the event and then create a setInterval timer that checks the current array length against the previously stored length. If the length has changed, I would then need to trigger my custom event from inside the setInterval.
Is there a way to register an event for my array and have it fire automatically when the length changes?
Custom events are in the W3C spec, but none of the major browsers support them. This is why several other users have suggested 3rd party libraries. Prototype, YUI, JQuery, and most others have these capabilities. You can also roll your own.
If you'd like to see what some custom event syntax might look like, you can take a look at this tutorial for Prototype custom events. Some important points:
Prototype custom events must be attached to DOM elements, so that they can bubble like native events.
They must be in a prefix:event syntax in order to fire
They can contain a highly-useful memo parameter that allows any arbitrary context or set of objects to bubble with the event.
why don't you write a method addElement for your array that you'll use whenever you want to insert elements,that way you will be able to write code in the event of array.length change.
same thing with removeElement.
Events are not meant to be used for this kind of thing.