Callbacks are a nice way of Iversion of control, but are even more powerful with deferred objects.
Basically callbacks are a way to pass back the control from a called function, the deferred/promise just do the opposite: it returns the control the called function.
Consider this scenario: a table widget, with the classic delete/modify buttons next to each row. Since the table widget is a generic component, we want to handle the delete operation on the model outside the widget, and we don’t event want to extend the generic object to do that, we want to user a callback:
In the example above: the callback first calls the backend to remove the record and then removes the row from the table (I mean the DOM). In order to do this: it needs to know something about the table widget (in this case, the method “remove_row”).
But what if we could pass the ball back to the widget? Let’s rewrite it with a deferred object:
It’s more linear but, most important, the callback knows nothing about the remove_that_damn_row_from_the_dom method of the widget, it just passed back the control, it’s like saying “I’m done, it’s your turn”.
More separation, less documentation to read, easier to implement, less errors.
On the widget side, the callback should be treated this way
Eventbroadcast it’s a small library to improve the functionality of bind()/trigger() methods.
This plugin extends jQuery with the method $.trigger(‘
The main problem with the classic jQuery $(‘
With the Publish/Subscribe pattern it’s easy to decouple the code in charge to create the event from the code that receives it: the event emitter doesn’t know (and doesn’t care), at runtime, who is listening to the event (speaking with the words of academics, it’s not aware of the topology of the elements).
The more the code is decoupled, the more is maintanable.
jFsm stands for jQuery Finite State Machine and it’s a little script to help handling UI controls passing from a state to another.
Have you ever found yourself in a situation writing code like this?
In this script some controls must be visible and enabled in a state (for example step #1 of a wizard) and/or invisible in the next state.
Nothing wrong with the code above, but as soon as the complexity of the UI grows up, the code become un-mantainable.
Wouldn’t be easier to define a set of possible states for our UI (for example step1, step2 and step3 for our multistep form) and define for each of them the behaviour of the UI components
Then with a simple command we change the state $.jfsm(‘step3′) and it will do the magic for you: .button2 and .button1 are hidden, .save and .letsGoBack are visible and the control .controlToDisableInStep3 gains the class ‘disabled’.
At first sight seems I’ve written more code, perhaps it’s true, but I’ve grouped this kind of logic in just one place and it’s easier to add element to the UI.
$(‘element-selector’).jfsm(‘mystate’,state-descriptor): Define a descriptor for an element on the state ‘mystate’. The descriptor is an hash array which may contains one or more of these keys:
$.jfsm(‘to-state’): Change the state the to ‘to-state’, triggering all the UI changes defined with the function above.
It always return a Deferred() object since the changes to the UI might be asynchronous.
In addition, when a transition is completed, an event ‘jfsm-state’ is triggered on $(‘body’), the first argument is the new state name.
$.jfsm(new_descriptor,descriptor_handler,predefined_value): Define a new key for the state descriptor object
Suppose I want to hide/show elements during transition using a fancy fade in/out effect.
First of all, register the *fade* key for the state descriptor:
Then define the behaviour of the button
And now $.jfsm(‘step1′) and $.jfsm(‘step2′) will switch the state between step1 and step2, happily fading in and out your button.
But we can do even better, jfsm handles correctly deferred objects, we can improve the handler in this way:
The event ‘jfsm-state’ will be triggerd only when the fade transition is completed, or I can just use the deferred object returned by $.jfsm:
View the repository on GitHub
Free for personal and commercial use under the MIT/GPL license used by the jQuery core libraries.