{ bob.yexley.net }

software development, sports, the outdoors, faith, life...

JavaScript Modules to Support Interactive Web Applications

JavaScript The web has evolved and the standards for browser applications have been raised to new levels over the past five years. People just expect more (and rightfully so) from web applications. It used to be that whenever I used any kind of JavaScript (to which, from this point forward, I will refer to as simply, JS, thankyouverymuch) in my web apps that I would pretty much just reference a .js file and randomly jam a bunch of functions in it, and hope someone (a team member, perhaps) didn’t notice them closely enough to attempt to use one in a way in which it wasn’t intended to be used. Knowhatimean? Ever been there, or done that? Perhaps you’re there now.

At some point…not sure exactly when…I guess it was probably about six or eight months ago or so…I finally got to a point where I said to myself, “self…there has GOT to be a better way.” So I did some Googling…and as it turns out, I was right…

The module pattern

Some of the big things that I found myself longing for as the JS I was writing started to get more and more complex, was encapsulation, reuse and statefulness. The searching I did (check out the link above) quickly showed that the module pattern would give me all of that and more. I highly recommend starting with the first link in those results, its a fantastic article by ben cherry that covers how to implement the module pattern with JS in very simple and understandable terms (seriously, if this subject interests you at all, go read it…this page isn’t going anywhere…you may not even want to come back after reading it…).

I started slowly with this pattern to support a few web applications that required some semi-complex client-side interactions, and have been very pleased with how it has worked out so far. Here’s a stripped down sample of the format that the modules I’ve been writing have taken:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// pageModule.js
var pageModule = (function () {

// Private members
  var selectors;

// Public operations
  return {
      Init: function (params) { return init(params); },
      AnotherFunction: function () { return anotherPrivateFunction(); }
  };

// Private operations
  function init(params) {
      selectors = params;
      // ...
  }

  function anotherPrivateFunction() {
      // ...
  }

})(); // pageModule

A particularly appealing feature of this approach to writing JS is that it is totally isolated and easily testable using a JS unit test framework like QUnit or JsTestDriver.

Pulling it into a web page

I’ve found this approach to support interactive client-side functionality in web applications very nicely as well, though, this is an area where I admittedly have some questions as to my approach. I’ve been wondering if I sense a slight code smell with the following approach, and would appreciate some feedback. But anyway, here’s how I’ve been using it.

Being the .NET developer that I am, the following is an example of a razor view from an ASP.NET MVC app, that uses the above module, but this same approach could be used with any web frameworks view engine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// page.cshtml
@model PageViewModel

@{ ViewBag.Title = "Page Title"; }

@section PageHeadContent {
  ...
}
<div id="PageContent">
  <ul class="some-list">
      <li>...</li>
  </ul>
</div>
@section PageScripts {
  ...
  <script src="/js/pageModule.js"></script>
  <script>
      var pageModuleParams = {
          PageContentContainer: '#PageContent',
          ListOfStuff: '.some-list'
      };
      pageModule.Init(pageModuleParams);
  </script>
}

See what I did there? So, the idea here is that the JS module itself knows absolutely nothing at all about the page that it is supporting. But, it can still fully support and manipulate DOM elements on the page, because the page feeds it the selectors it is (obviously) fully aware of by passing the pageModuleParams object into the module through the publicly exposed Init operation, which sets the internal selectors variable. From that point on, the module itself, internally, can wire up internal operations (event handlers, ajax calls, etc) that can act on elements of the page through selectors that were passed in from the page, and yet still remain totally decoupled from the page.

So what do you think? This approach has been working fairly well for me for a while now, but it wouldn’t surprise me a bit to know that there are much better ways to handle this. Any suggestions or recommendations? Learning new and better ways of doing things (especially if they make my life easier) is something I love…so I’m totally open to feedback here. Was this useful?

Comments