Jan, 2014





Arvind Ravulavaru

Contents

  • Backbone - What is it?
  • MVC - What, Why & Where?
  • Understanding Models, View & Controllers
  • Setting up Backbone
  • Sample Application
  • AMD - What & How?
  • Backbone & Testing?
  • Resources



MVC

MVC -What is it?

  • Models  - represent the domain-specific knowledge and data in an application. (e.g., a User, Photo, or Todo note) 
    • Models can notify observers when their state changes.
  • Views  - The user interface in an application (e.g., markup and templates)
    • They observe Models, but don’t directly communicate with them.
  • Controllers handle input (e.g., clicks, user actions) and update Models.

MVC


MV*

  • JavaScript MVC frameworks don’t always strictly follow the MVC pattern

  • Some solutions (including Backbone.js) merge the responsibility of the Controller into the View, while other approaches add additional components into the mix.

  • For this reason we refer to such frameworks as following the MV* pattern; that is, you’re likely to have a Model and a View, but a distinct Controller might not be present and other components may come into play.


Which MV* Framework to pick?

A Simple Todo List

Todo Demo


Who's using backbone?

Backbone Setup

Dependencies
  • jquery
  • underscore
  • backbone
  • JSON2.js (Browsers that do not support JSON by default)


Backbone Model

Backbone Collections

Backbone View

  • Contain the logic behind the presentation of the model’s data to the user

  • Achieved using JavaScript templating (e.g., Underscore Microtemplates, Mustache, jQuery-tmpl, etc.)

  • A view’s render() method can be bound to a model’s change() event,  to instantly reflect model changes without refresh.

Backbone View

Backbone Controller - ~"Routers"*

  • Provide a way for you to connect URLs

  • Pages that need to be bookmarkable, shareable or back-button-able

  • Sample Backbone Controller

  • Backbone.history

  • monitor hashchange - Backbone.history.start()

  • navigate()

RESTful Persistence

Backbone's Sync API

  • Stitches all the RESTful operations underhood
    • Backbone.emulateHTTP = false; // set to true if server cannot handle HTTP PUT or HTTP DELETE
    • Backbone.emulateJSON = false; // set to true if server cannot handle application/json requests
  • Uses the save method
    • Todos.save(updatedModel,{options}); 
  • Overriding Backbone.Sync()

A Library Application


Library Application Walkthrough


  • Model - Book/ Collection - Library
  • View - One Book Entity
  • Controller - One Book/All Books
  • Demo
  • Main.js - Walkthrough

AMD

  • Asynchronous Module Definitions (API)

  • Designed to load modular code asynchronously in the browser 

  • Particularly well suited for the browser environment where  synchronous loading of modules incurs  

    • Performance Issues

    • Usability
    • Debugging
    • Cross Domain
  • Ex: Require.js, yepnope.js

AMD + js MVC

  • require.js + Backbone.js = Modular M.V.C. Development
  • Demo
  • Folder Structure
  • Jasmine (B.D.D) & Sinon

Jasmine

  • B.D.D - Behaviour-Driven Development

  • Source
    var helloWorld = function() {
        return "Hello world!";
        };
    
    Test Case
    describe("Hello world", function() {
        it("says hello", function() {
            expect(helloWorld()).toEqual("Hello world!");
        });
    });
    
  • Further Reading

Sinon

  • Provides fake objects – spies, stubs and mocks – for testing your JavaScript code
  • Fake It
    after(function () {
        // When the test either fails or passes, restore the original
        // jQuery ajax function (Sinon.JS also provides tools to help
        // test frameworks automate clean-up like this)
        jQuery.ajax.restore();
    });
    
    it("makes a GET request for todo items", function () {
        sinon.stub(jQuery, "ajax");
        getTodos(42, sinon.spy());
    
        assert(jQuery.ajax.calledWithMatch({ url: "/todo/42/items" }));
    });
    
  • Further Reading

Testing Backbone

  • describe("when instantiated with model literal", function() {
      beforeEach(function() {
        this.todoStub = sinon.stub(window, "Todo");
        this.model = new Backbone.Model({
          id: 5, 
          title: "Foo"
        });
        this.todoStub.returns(this.model);
        this.todos = new Todos();
        this.todos.model = Todo; // reset model relationship to use stub
        this.todos.add({
          id: 5, 
          title: "Foo"
        });
      });
        
      afterEach(function() {
        this.todoStub.restore();
      });
    
      it("should add a model", function() {
        expect(this.todos.length).toEqual(1);
      });
        
      it("should find a model by id", function() {
        expect(this.todos.get(5).get("id")).toEqual(5);
      });
    });
    

Resources



Questions?






@aravulavaru