Chariot Training Classes

Training Courses

I run Chariot's training and mentoring services. We provide training in AngularJS, HTML5, Spring, Hibernate, Maven, Scala, and more.

Chariot Education Services

Technology

Chariot Emerging Tech

Learn about upcoming technologies and trends from my colleagues at Chariot Solutions.

Resources

Chariot Conferences

Podcasts

Entries in quizzo (1)

Saturday
Feb162013

Quizzo - it's baaack - but this time for keeps

Hey everybody!

For my ETE talk, and our internal Chariot Day conference beforehand, I've taken on client-side Single-Page-Web-Application (SPWA) Javascript programming. I started by attempting to learn Backbone.js, but this poor old server-side programmer with a smattering of front-end talents grounded hard on the shallow waters of confusion.

I was not alone. At SpringOne/2GX 2012, VMware's Craig Walls hosted a talk comparing SPWA frameworks, and discussed Backbone's lack of a 'day one story' - a starting point example. He was really interested in the Walmart Labs projects Thorax and Lumbar, which are attempting to bring some higher-level structure and organization to the code base. Also, I ran into the emerging but not yet complete Yeoman
Then Chariot's Don Coleman turned me on to Addy Osmani's TodoMVC project - it implements the same task list use case in oh, about 18+ frameworks.

I spent time looking at each of them and AngularJS caught my eye. It has two-way instant data synchronization, is agnostic with respect to your models, contains a good basic validation scheme, and uses tags and attributes salted to the templates to expose a 'ViewModel' to the view.

What is a view model?

A ViewModel is an element of your MVC model that should be exposed to the page. Spring MVC has this concept - we put things in the Model object to show to the users, but rarely do we put true domain objects in there. If you have web-only beans that you send back-and-forth to the UI, chances are you're using the ViewModel pattern (please let me know if that is a wrong assumption).

A sample view

Let's review some code from our current Quizzo-ETE project, a collaboration with David Turanski of VMware for our upcoming Modern Spring Web Applications talk. We're using AngularJS and Spring to show enterprise developers how to leverage their skills in Spring but also quickly get onboard with a very powerful SPWA framework.

First, a simple view fragment, showing how to emit model elements:

<tr>
    <th span="2">Statistics</th>
</tr>
<tr>
    <th>Score</th>
    <td>{{statistics.score}}</td>
</tr>
<tr>
    <th>Max Score</th>
    <td>{{statistics.maxScore}}</td>
</tr>
<tr>
    <th>% Correct</th>
    <td>{{statistics.percentCorrect}}</td>
</tr>

So, you can see the handlebars-style substitutions of ViewModel elements using the {{ and }} characters.

A sample Angular controller

Here is the Angular controller that put the data in there in the first place:

myApp.controller('ByeCtrl', function($scope) {
  $scope.statistics = {
    "score": "130",
    "maxScore": "150",
    "percentCorrect": "86%",
    "topScorers": ['phil', 'joe', 'alex']
  };

The $scope object is our ViewModel. We're adding a Javascript object called

statistics

to it, hardcoding it for now.

Two-way databinding

The cool thing is that if anything on the page changes the objects, the page changes immediately. A click, an event, even a message from the outside world, can trigger a UI update. The same works the other direction with form elements. Consider this fragment:

  <form class="panelform left">
    <p>
        <label for="nickname"><b>Nickname</b></label>
        <input type="text" 
               ng-model="nickname"
               ng-change="verify_nick(nickname)"
               id="nickname"
                /> 
        <span ng-show="badNick" class="error">
                        Nickname already used...</span>

    <button id="join" ng-click="join_game($location)"
      ng-show="!badNick && nickname">Join</button>
    </p>
</form>

Handling events

The input tag has some special attributes in it - ng-model, which automatically binds the typed in value (live, no less, not even requiring a submit) to a $scope element called nickname. We trigger verification by calling a controller method called verify_nick, passing the nickname into the call. Here is what the controller looks like:

myApp.controller('JoinCtrl', function ($scope, $location, PlayerService, QuizManagerService) {

  $scope.verify_nick = function () {
    var result = PlayerService.searchNickName($scope.nickname);
    $scope.badNick = result;
  };

  $scope.join_game = function (nickName, emailAddress) {
    PlayerService.setNickName(nickname);
    QuizManagerService.startQuiz();
    $location.path("/play");
  };


});

You can see interactions with several objects. For Spring fans, we inject objects in a similar way to how Spring MVC does it - add it to the function's parameter list and it gets injected. NICE.

Services

We inject and use several objects:

  • $scope - our ViewModel
  • $location - allows us to change the page fragment we're showing
  • PlayerService, QuizManagerService - these are stateful service objects that live inside of the browser. Think of them as holding your state and calling business methods, and you're on the right track.

You should note that in this function, we're adding two other named functions to the ViewModel - verify_nick and join_game. Also, for those Spring developers you'll see us delegating most work to our named Service and built-in Angular objects. Just like a good MVC, it's just a front-end. The services do all the work.

Summary

That's all for now, and if you check out the commit with version 33607951b734a0f1cfc8a710b41abd8664cc3e8f you can run the app this way:

  • first, install node.js - 0.8 +
  • next, do a 'npm install -g express'
  • cd to ./angular-prototype/app
  • run the server with node server.js
  • browse to http://localhost:4567

It looks TERRIBLE right now. But it is a working app with several panes. I'm using Twitter bootstrap on the front-end so expect some ugliness until I get that smoothed out.

To re-iterate, our code is online - please feel free to watch our progress and comment away here if you like, but expect lots of silly steps as we move along). It's at http://github.com/krimple/quizzo-ete.