Skip to content

Instantly share code, notes, and snippets.

@crh
Created October 8, 2012 12:16
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save crh/3852220 to your computer and use it in GitHub Desktop.
Save crh/3852220 to your computer and use it in GitHub Desktop.
Backbone & Yeoman

Backbone.js and yeoman

description

this is a list tutorials for building web application using backbone.js and yeoman. We are building a Photo Gallery JS App from Backbone Fundamentals

Requirements

Steps

backbone scaffolding

$ yeoman init backbone
.
|-app
|---scripts
|-----collections
|-----helpers
|-----models
|-----routes
|-----templates
|-----vendor
|-----views
|---styles
|-test
|---lib
|-----mocha-1.2.2
|---runner
.
|-Gruntfile.js
|-package.json
|-app/
|---404.html
|---favicon.ico
|---index.html
|---robots.txt
|---scripts/
|---main.js
|-----collections/
|-------application-collection.js
|-----helpers/
|-----models/
|-------application-model.js
|-----routes/
|-------application-router.js
|-----templates/
|-------application-collection.js
|-----vendor/
|-------backbone-min.js
|-------jquery.min.js
|-------lodash.min.js
|-----views/
|-------application-view.js
|---styles/
|-----main.css
|-test/
|---chai.js
|---expect.js
|---lib/
|-----mocha-1.2.2/
|-------mocha.js
|-------mocha.css
|---runner/
|-----mocha.js

what you got?

  • html5 boilerplate

  • TODO find out if [Modernizr] is included in yeoman init backbone:app

  • js libraries

    • jquery
    • backbone
    • lodash what: functional programming library
  • testing TODO rnd differences expect VS chai

    • expect what: assertion toolkit (BDD-style)
    • chai what: assertion library (TDD/BDD)
    • mocha what: test framework
  • Build file Gruntfile.js what: build file configuration for Grunt See: https://github.com/gruntjs/grunt/blob/master/docs/getting_started.md TODO rnd, if we can use all grunt commands with yeoman similar to pom.xml in Apache Maven

  • Project metadata /package.json what: metadata about your project, e.g. name, author, version, etc Node Package Manager use it. similar to pom.xml in Apache Maven

    example:

{
  "name" : "underscore",
  "description" : "JavaScript's functional programming helper library.",
  "homepage" : "<a href="http://documentcloud.github.com/underscore/"http://documentcloud.github.com/underscore/</a",
  "keywords" : ["util", "functional", "server", "client", "browser"],
  "author" : "Jeremy Ashkenas <<a href="mailto:jeremy@documentcloud.org"jeremy@documentcloud.org</a>",
  "contributors" : [],
  "dependencies" : [],
  "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"},
  "main" : "underscore.js",
  "version" : "1.1.6"
}

Models

create a model 'photo'

NOTES:

  • domain specific
  • manage structured application data
  • examples: Book, Author, Person, Email, etc
$ yeoman init backbone:model photo
bbTut.Models.PhotoModel = Backbone.Model.extend({

  // default attributes for the model
  defaults: {
    'src': 'placeholder.png',
    'caption': 'A default image',
    'isViewed': false,
    'tags' : []
  },
  initialize: function() {
    console.log('init photo model...');
    console.log(JSON.stringify(this));
  }
});

In Action

  • edit /app/index.html
  <!-- [...] -->
  <script src="scripts/models/photo-model.js"></script>
  • edit /app/main.js
window.bbTut = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  init: function() {
    console.log('Hello from Backbone!');
    new bbTut.Models.PhotoModel({
      src: 'placeholder.png',
      caption: 'Me at google i/o 2012',
      tags: ['#io12', '#io2012']
    });
  }
};

$(document).ready(function(){
  bbTut.init();
});
  • $ yeoman server
  • open Chrome http://localhost:3501
  • open Chrome Developer Console
Hello from Backbone! main.js:7
init a photo model. photo-model.js:9
{"src":"placeholder.png","caption":"Me at Google I/O 2012","isViewed":false,"tags":["#io2012, #me, #google"]} photo-model.js:10

Collections

A collection is a set of models.

NOTES:

  • grouping mechanismn
  • instead to 'watch' each model, 'watch' collection.
$ yeoman init backbone:collection photo
bbTut.Collections.PhotoCollection = Backbone.Collection.extend({

  model: bbTut.PhotoModel,

  // return all photos that have been viewed.
  viewed: function() {
    return this.filter(function(photo) {
      return photo.get('isViewed');
    });
  },

  // return all photos that have _not_ been viewed.
  unviewed: function() {
    // see: http://documentcloud.github.com/underscore/#without
    return this.without.apply(this, this.viewed());
  }
});

In Action

  • edit /app/index.html
  <!-- [...] -->
  <script src="scripts/models/photo-model.js"></script>
  • edit /app/main.js
window.bbTut = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  init: function() {
    console.log('Hello from Backbone!');
    new bbTut.Models.PhotoModel({
      src: 'me_at_io.png',
      caption: 'Me at google i/o 2012',
      tags: ['#io12', '#io2012']
    });

    new bbTut.Collections.PhotoCollection([{
      src: 'me_at_io.png',
      caption: 'Me at google i/o 2012',
      tags: ['#io12', '#io2012']
    },
    {
      src: 'fiz-karlsruhe-building.png',
      caption: 'FIZ Karlsruhe Main Building',
      tags: ['#fiz']
    }
    ]);
  }
};

$(document).ready(function() {
  bbTut.init();
});
  • $ yeoman server
  • open Chrome http://localhost:3501
  • open Chrome Developer Console
Hello from Backbone! main.js:7
init a photo model. photo-model.js:9
{"src":"placeholder.png","caption":"Me at Google I/O 2012","isViewed":false,"tags":["#io2012, #me, #google"]} photo-model.js:10

Views

NOTES:

  • visual representation of model.
  • views observe models, models notify changes, views update themselves.
  • user interact with views.
    • reading example: seeing image, read the caption, read a list of tags.
    • editing example: edit caption, replace image source, remove tag.
  • 'dumb' : limited knowledge of models.
$ yeoman init backbone:view photo

Templating

Notes:

  • create large HTML Markup in Memory through string concatenation is expensive
var html = "<ul>";
for(var x=0; x < people.length; ++x){
  var person = people[x];
  html += "<li>" + person.name + "</li>";
}
<ul>
  <li> <%= person.name => </li>
</ul>
  • JS templating libs: Handlebar, Mustache, HAML, etc
  • storage
    • inline, within script tags
      • using custom type : 'text/template'
      • e.g.
<script type="text/template">
  Hello <%= person.name =>
</script>
  • external files
    • enables just-in-time loading

Comparison

Handlebars
<li class="photo">
  <h2>{{caption}}</h2>
  <img class="source" src="{{src}}"/>
  <div class="meta-data">
    {{metadata}}
  </div>
</li>
Underscore Microtemplates
<li class="photo">
  <h2>{{caption}}</h2>
  <img class="source" src="{{src}}"/>
  <div class="meta-data">
    {{metadata}}
  </div>
</li>

Controller

Router

Namespacing

Notes:

  • avoid collisions with other object and variables in global namespaces. Example???
  • JS does not have namespace feature
    • workaround: use closures

Namespacing

  • Single global variables
  • Object Literals
  • Nested Namespacing
@addyosmani
Copy link

Hi there! My name is Addy Osmani. I wrote Backbone Fundamentals and helped create Yeoman. It's really interesting to see someone trying to write a tutorial using parts of both projects :)

I was wondering - would you be interested in expanding on this tutorial into something we could include in the book?

In recent times, I've updated the Basics section to focus more on creating a Todo application, but you could just as easily do the same with a similar workflow here.

e.g show folks how to create each of the files needed for views, routes and so on (we have a TodoMVC backbone app over at https://github.com/addyosmani/todomvc/tree/gh-pages/architecture-examples/backbone) which could be used for the code example population.

Let me know if that would be of interest :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment