Patterns of JavaScript UI Widget Instantiation

Have you considered all of the patterns for instantiating a widget these days? That is, in a strictly old school OOP dialect, have you examined the numerous patterns propagated by widget vendors for constructing an instance from a widget class? The imperative and declarative divide alone is enough to give a wannabe front-end developer Programmatic Anxiety Disorder or PAT (yup, I made that up). Combine that with the development nuances associated with either style and one could quickly become overwhelmed with diverging methodologies and programming world views.

Choosing which pattern will create and run a widget in an application has become a rather complicated enterprise. Picking the “right one” is almost always a subjective decision.

Some widget vendors offer just a single approach, while others offer multiple ways to get the job done. Which should you use? I won’t presume to know which is best for you and will dispense with the notion of writing an article prescribing the ideal pattern to adopt. “Ideal,” in this context, is almost always relative to talent, time, and trade-offs. I like to call these the three t’s of development decision making.

What I intend to offer in this article is more of an overview, not a recommendation. I merely want to showcase some of the common patterns used by widget vendors so that the unaware developer can familiarize themselves with the options.

Five Common Patterns

The following five patterns for initializing a widget are fairly common among UI widget toolkits. At the very least, some degree/variation of what is listed below is commonly offered.

  1. The imperative jQuery plugin instantiation pattern (aka the DOM blinders pattern)
  2. The imperative constructor instantiation pattern (aka the OOP sacred cow pattern)
  3. The declarative markup instantiation pattern (aka the dusting of markup with declarative fairy dust pattern)
  4. The declarative MVVM instantiation pattern (aka the binding fairy dust with MV* pattern)
  5. The declarative AngularJS instantiation pattern (aka the directive fairy dust with MV*+ pattern)

This article will demonstrate each of these instantiation patterns using Kendo UI. However, it is not my exact aim here to specifically teach you about Kendo UI, but, rather, my goal is broader.

I want to bring attention to the patterns themselves in order to think about and contrast them. Pay close attention to the side effects each pattern has on programming a widget instance throughout its life cycle (i.e. calling methods, binding events, and accessing instance properties).

All the code examples below have the same end in mind. Create a slider widget that keeps the current slider value updated in a separate portion of the DOM (e.g. <h5>results: <span>10</span></h5>). Study the code and consider how each pattern will effect the code you hinge it too.

DOM Blinders and OOP Sacred Cows

The first two patterns (numbers 1 and 2 from the list above) both place a priority on writing JavaScript alone that tells the interpreter how to do something. Of course, the constructor pattern would never want to be associated with the jQuery pattern, but in this context they are sailing in the same ship to the same destination – the constructor pattern just wont speak to, or look at, the jQuery pattern.

Both patterns start and end in the code. These patterns are typically for those people who don’t want programmatic logic mixed among HTML markup.

1. the imperative jQuery plugin instantiation pattern (aka the DOM blinders pattern)

JS Bin

2. the imperative constructor instantiation pattern (aka the OOP sacred cow pattern)

JS Bin

Different Kinds of Fairy Dust

The last three patterns (numbers 3 through 5 from the list above) place a priority on describing, using HTML markup, what you would like to happen, and then a JavaScript-driven abstraction makes that occur in the shadows. Some say hip-hip hooray and some prefer not to take part.

These patterns are very much in vogue today. They swing the pendulum away, often far away, from a traditional understanding of a view, model, and controller. And while a lot can be describe in HTML, it’s certain that not everything can be, which means imperative programming cannot be completely avoided.

3. the declarative markup instantiation pattern (aka the dusting of markup with declarative fairy dust pattern)

JS Bin

4. the declarative MVVM instantiation pattern (aka the binding fairy dust with MV* pattern)

JS Bin

5. the declarative AngularJS instantiation pattern (aka the directive fairy dust with MV*+ pattern)

JS Bin

Conclusion

Each pattern speaks to each developer differently. Which one should you use? I have no idea. More importantly, I just want everyone to be be aware of each, and understand briefly the implications.

Header image courtesy of NapInterrupted

Comments

  • Pingback: Dew Drop – April 25, 2015 (#2001) | Morning Dew()

  • steve

    You have missed one fundamental pattern which is tidier. Requiring the specific widget logic immediately after the html snippet. require([‘mywidget]’). Init( dynamic server side variables can go here.)
    Then you can use any plugin, jquery, bootstrap, kendo, take your pick and manage all your logic in the external js file.

    • This is an architectural pattern. I was more focused on the instantiation of the widget itself. I am working on another article that explains how to use Babel & ES6 modules to do exactly what you are suggesting. Very important pattern. Actually more important than the instantiation. 🙂

      I’ve included a code sample to showcase pulling in only what you need into a single js file. After you get the architecture right, Kendo UI gives 6’ish pattern for actually creating the widget. In the code sample I am using the jQuery pattern, but any will do.