Using the MVW pattern in an SPA

It should now be clear to you that MVW is not a precise architectural pattern, but rather a paradigm in which you have a Model, a View, and a nebulous third component, or more components, depending on how fine-grained you decide to break down your separation of concerns. Everything falling within that gray area is based on what type of application you are building, what architectural components you are comfortable with as a developer, and what frameworks and libraries you are working with.

Building a simple JavaScript SPA

The complexity of your SPA should always be a factor in what technologies you use to build it. More to the point, you should not go into every project assuming you will always use a certain technology stack or framework. This rule goes for the MEAN stack as well.

Let's take the User Model example from earlier, and the accompanying Handlebars template View, and actually build it out as an SPA, complete with the AJAX request to retrieve the User Model data. For something simple like this, using AngularJS and the MEAN stack would definitely be overkill. Let's begin by using the NPM, Bower, and Grunt environment you set up in Chapter 1Getting Organized NPM, Bower, and Grunt. So how do we proceed?

Creating the Model

The Model is the simple JSON object of user data we defined earlier. Rather than setting up a database for this, let's simply place it in a text file and name it user.json:

{ 
    "id": 1, 
    "name": { 
        "first": "Philip", 
        "last": "Klauzinski" 
    }, 
    "title": "Sr. UI Engineer", 
    "website": "http://webtopian.com" 
} 

Save the file to the same directory as your package.json, bower.json, and Gruntfile.js. Feel free to replace the user information with your own for this example.

Creating the View

The View for this example will be the web template document we defined earlier with a definition list containing user information:

<h1>User Information</h1> 
<dl> 
    <dt>Name</dt> 
    <dd>{{name.first}} {{name.last}}</dd> 
    <dt>Title</dt> 
    <dd>{{title}}</dd> 
    <dt>Website</dt> 
    <dd>{{website}}</dd> 
</dl> 

Save this file to the root directory of your project as well and name it user.handlebars.

Setting up frontend assets

We are not creating a complex SPA in this case, so we will not use any frontend frameworks, but we do want to install a few libraries to make development easier.

If you followed the examples in Chapter 1, Getting Organized with NPM, Bower, and Grunt you should already have jQuery installed via Bower. If you have not yet installed it, go ahead and do so now:

$ bower install jquery --save

We will use jQuery for handling AJAX requests and DOM manipulation within the SPA.

Now let's install the Handlebars library for parsing our web template View:

$ bower install handlebars --save

Compiling web templates

A web template has to be compiled to JavaScript before it can be parsed for expressions. This can be done in the browser using the Handlebars frontend library, but it means longer execution times when loading templates, and it also means loading a larger library asset file on the initial page load. The initial page load is critical for a SPA because you do not want the user waiting a long time for your app to download assets and prepare the page for the initial View. Additionally, if you want to separate your Views into separate files, as we did with user.handlebars, then those View files have to be loaded asynchronously at some point to hand over to the compiler.

Precompiling web templates

To circumvent large asset payloads and extraneous round trips to the server to fetch Views, Handlebars allows you to precompile web templates to JavaScript so that they can be used immediately within your app. This gives you the ability to separate your Views into different files and keep things organized and still maintain a lower initial page load.

For this example, let's install the Handlebars Node.js package globally so that it can be used from the command line in any directory:

$ npm install handlebars -g

This will now allow you to compile your templates on the command line to create a precompiled JavaScript template file you can use in your SPA. From the root of your project directory, enter the following:

$ handlebars *.handlebars -f templates.js

This command is telling the Handlebars compiler to take all files with the extension .handlebars (in this case only user.handlebars) and compile them to a single file named templates.js. This could allow to you have 100 separate web template View files and precompile them to one JavaScript file, for example. This is a good practice because it allows you to map each View file to a REST API endpoint on your server side. In the case of our SPA example, our endpoint will be requesting the user.json file through AJAX.

Handling server HTTP requests

Now we will install the PayloadJS library for handling REST requests within the SPA:

$ bower install payloadjs --save

PayloadJS will allow us to easily make AJAX requests triggered from our SPA markup by using custom data- HTML attributes to define behaviors and parameters in the DOM.

Creating the SPA layout

One of the most important pieces of a SPA is the single page itself, or the layout for your app. This is the one and only server-side HTML page that you will load in order to initialize and display your app.

Create a file in the root of your directory named index.html, and enter the following code into it:

<!doctype html> 
<html> 
    <head> 
        <title>My Application</title> 
    </head> 
    <body> 
        <p><a href="#" data-url="/user.json" data-template="user" data-selector=".results">Load user data</a></p> 
        <div class="results"></div> 
        <script src="/bower_components/jquery/dist/jquery.min.js"></script> 
        <script src="/bower_components/handlebars/handlebars.runtime.min.js"></script> 
        <script src="/bower_components/payloadjs/payload.js"></script> 
        <script src="/templates.js"></script> 
        <script> 
            Payload.deliver({ 
                templates: Handlebars.templates             
            }); 
        </script> 
    </body> 
</html> 

This will be the main layout page for your SPA. You will notice that script tag references have been added that point to jQuery, Handlebars, PayloadJS, and the templates.js file we created. These are all of the assets you will need loaded in order to run this SPA. Additionally, the Payload.deliver() command is run at the bottom of the page and passed an object to overwrite any of its default initialization options. This method simply initializes PayloadJS to drive the behavior within the DOM indicated in the data- attributes on the link with the text Load user data. In this case, we are setting the templates property that is passed in to Handlebars.templates, since that is the namespace containing our Handlebars template.

For more information on using PayloadJS, please see payloadjs.com.

Serving the SPA

Now you have all of the necessary files in place to run this simple SPA. The only thing left is a local server to run and load the index.html file for testing. Let's install a simple HTTP server with NPM for this purpose:

$ npm install http-server -g

Install this package globally so that it can be run from the command line. This simple Node.js HTTP server can be run specifying any local directory as your server. In this case, we want to run the server for the current project directory:

$ http-server ./ 

After running this command, you should see something similar to the following output in your console:

Starting up http-server, serving ./
Available on:
  http:127.0.0.1:8080
  http:192.168.0.2:8080
Hit CTRL-C to stop the server

This indicates that the HTTP server is running and available locally.

Now you should be able to go to a browser and load the URL localhost:8080 and you will see the contents of the index.html page you created. The only visible content of the page is the link with the text Load user data. If everything is set up properly and you click on that link, you should notice a Loading... indicator below it for a brief moment, followed by the contents of the user.handlebars template file populated with the data from the user.json file loaded into the page:

Serving the SPA

The full page with the response after clicking on the link should look similar to the preceding screenshot.

Overview of a simple JavaScript SPA

So we have created a simple JavaScript SPA using a general MVW pattern with the following components:

  • Model: user.json
  • View: user.handlebars
  • Precompiled templates file: templates.js
  • SPA layout page: index.html
  • HTTP server: Node.js http-server package

This is about as simple as it gets, but you have created an SPA nonetheless. This example should give you an idea of how powerful JavaScript can be for creating a single page application. Feel free to extend this simple SPA with more Model data files, additional web template Views, some CSS, and a bit of your own creativity.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.87.161