ECMAScript 6 in action with the view

Last time (ECMAScript 6 in action with the inheritance and the models) we’ve created an “humansView” quickly. Today we’re going to use Handlebars to make something more “à la Backbone”. Handlebars is a javascript templating library.

Modify bower.json

{
  "name": "es6-project",
  "version": "0.0.0",
  "dependencies": {
    "uikit": "~2.8.0",
    "jquery": "~2.1.1",
    "handlebars": "~1.3.0",
    "traceur": "~0.0.49"
  },
  "resolutions": {
    "jquery": "~2.1.1"
  }
}

We’ve had "handlebars": "~1.3.0" (handlebars dependency). Now, type this command: bower update.

Update collection.js

We need to add a toJson() method to the collection, then we can pass simple json object to handlebars templates:

toJson () {
  return this.models.map((model) => model.fields);
}

Create a component ViewModel: HumansList

You can delete js/app/views/humansView.js, create a new directory: components in js/app/views with a new javascript file humans-list.js:

es6-project/
├── node_modules/
├── public/   
|   ├── bower_components/  
|   ├── js/          
|   |   └── app/
|   |        ├── core/
|   |        |   ├── model.js    
|   |        |   └── collection.js      
|   |        ├── models/
|   |        |   ├── human.js    
|   |        |   └── humans.js  
|   |        ├── components/    
|   |        |   └── humans-list.js      
|   |        └── main.js
|   └── index.html
├── .bowerrc
├── bower.json
├── package.json    
└── app.js

with this content:

class HumansList {

  view ()  { return `
    <ul>
      {{# each humans}}
      <li>{{id}} {{firstName}} {{lastName}}</li>
      {{/each}}
    </ul>
  `;}

  constructor (humansCollection) {
    humansCollection.addObserver(this);
    this.humans = humansCollection;
    this.template = Handlebars.compile(this.view());
    this.el = document.querySelector("humans-list");
  }

  render () {
    this.el.innerHTML = this.template({humans: this.humans.toJson()});
  }

  update (context) {
    this.render();
  }
}

export default HumansList;

Update main.js

import Human from './models/human';
import Humans from './models/humans';
import HumansList from './components/humans-list';

class Application {

  constructor () {
    $("h1").html("E6 rocks!")

    var humans = new Humans();

    var list = new HumansList(humans)

    humans.fetch().done(()=>{ /* get all humans from database */
      if(humans.size()==0) { /* no human in database, then populate the collection */

        var bob = new Human({firstName:'Bob', lastName:'Morane'});
        var john = new Human({firstName:'John', lastName:'Doe'});
        var jane = new Human({firstName:'Jane', lastName:'Doe'});

        /* save models */
        bob.save().done(
          () => john.save().done(
            () => jane.save().done(
              ()=> humans.fetch().done(console.log(humans)) /* fetch again */
            )
          )
        );

      } else { /* display humans */
          console.log(humans);
      }
    })
  }
}

$(() => {
  new Application();
});

We’ve changed:

  • import HumansList from './components/humans-list';
  • and var list = new HumansList(humans)

Last update

Modify index.html, you have just to add handlebars reference: <script src="bower_components/handlebars/handlebars.min.js"></script>:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>es6-project</title>
  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
  <link rel="icon" sizes="196x196" href="html5.png">
  <meta name="mobile-web-app-capable" content="yes">
  <link rel="stylesheet" href="bower_components/uikit/dist/css/uikit.almost-flat.min.css" />
</head>

<body style="padding: 20px">
  <h1></h1>
  <humans-list></humans-list>

  <script src="bower_components/jquery/dist/jquery.min.js"></script>
  <script src="bower_components/handlebars/handlebars.min.js"></script>
  <script src="bower_components/traceur/traceur.js"></script>

  <script>
    System.import('js/app/main');
  </script>
</body>
</html>

Now you can refresh http://localhost:3000/ and you’ll get a list of humans (again).

Next time we’ll use Polymer instead of our “from scratch” viewmodel component.

You can find source codes here : https://github.com/js-experiments/es6-project

Have a nice day!

blog comments powered by Disqus

Related posts