Event-Driven Design for DOM Manipulation


After one of the projects in my company had reached a point where refactor was not only recomended, but necessary to clean up the code and make it maintainable, I decided to use a different approach for DOM manipulation in the client facing web app. Since we were doing a major refactor (yes, it does exist!), I was given considerable leeway to choose a different way of dealing with the big problem of manipulating DOM elements.

After considerable discussion, we decided to go for an event-driven design. I decided to use Node’s event class as our event handler, and re-designed our models to emit a ‘change’ event whenever they changed, and UI elements would listen for these events and update to reflect those changes.

Event-driven programming simplifies UI handling. Let’s take the example of an updating speedometer inside a car racing game. Without events, every time the speed changed, jquery had to update the value of the speed-bar in the DOM by running the UI update code inside the model update code. Now consider the possibility that the developer wants to change the colour of a speed warning label whenever the speed exceeds a certain value. If he/she wants to add this feature, he has to find the place in the code where the speed is updated and then add another jquery code to update the colour of the speed warning label. This complicates the model update code and unnecessarily binds the UI with the model.

Event Driven Model

event-driven model

Now if this was using an event-driven model as shown above, the model would despatch a ‘speedUpdate’ event. The UI elements can listen to this separately:

//speed changes somewhere here
//event emitter emits an event
myEmitter.emit('speedUpdate', speed);

Now every UI element concerned with speeed changes has to listen to the speedUpdate event. This separates the model from the View. If the developer wants to add the speed warning label, all he/she has to do is to add the following line wherever the UI element is made.

myEmitter.on('speedUpdate', function(speed) {
	//do something with speed
}

This change required some big rewrites in our codebase. Since we were primarily using jquery to directly manipulate respective DOM elements whenever the model changed, we had to restructure the code to reflect the new approach. However, after we were done with the refactor, we realised it was well worth it. The speed at which new features could be added increased manifold, and the code became much more maintainable, extensible and readable. Following some standard event naming conventions, were were also able to significantly decrease the amount of DOM manipulation code we had in our codebase.

A highly recommended design approach for complicated large-scale applications involving complex UI-Model relationships!

-Taha


comments powered by Disqus