HOT TIP!

Command-T, fast file open

  • Big project with many folders, many tabs
  • Cmd-T, start typing file name
  • Textmate and Sublime Text have it
  • vim and emacs have plugins
  • even Github implemented

Single Page Applications

  • What is it?
  • Why is it cool?
  • What are the components?
  • How to build?

The good old days

The good old days

  • Every screen was many requests
    • Download all html/css/js/images
    • Parse HTML, build DOM
    • Parse CSS, paint page
    • Parse JS, execute code
  • Slooooooooooooooow

The good old days

  • Apps lived on the server
  • Many Users, 1 computer
  • Server went down, no more app
  • Scaling is expensive
  • Infrastructure complex

The good old days, SUCKED

  • Click, wait, click, wait
  • Lots of redundant work
  • Uneccessary bandwidth

No fun, no fun at all

to repeat, heres bad

...and now, good

What's the difference?

  • 1 page request
    • load html/css/javascript once
    • parsing, DOM building once
  • App lives in browser
    • less bandwidth
    • less server load
  • Immediately respond to user
  • Fassssssssssssssst!

Introducing MVC

  • Model, View, Controller
  • Easy to build
    • Separation of Concerns
    • Swap out layers
  • Easy to debug
    • Errors isolated
    • Code is more readable
  • Learn it, use it, love it!

The Model

  • Objects, Classes that represent data
    • ex. Player, Enemy in a Game
    • ex. Users, Friends in Social Network
  • Talks to database
  • Enforces database rules

The Model


          function Player(name) {
            this.name = name;
            this.score = 0;
          }

          Player.prototype.addPoints = function(points) {
            this.score += points;
          };

          Player.prototype.save = function() {
            localStorage.name = this.name;
            localStorage.score = this.score;
          };

          Player.prototype.restore = function() {
            this.name = localStorage.name;
            this.score = localStorage.score;
          };
          

The Model


          function initGame() {
            var myPlayer = new Player();

            myPlayer.restore();
            myPlayer.addPoints(1000);
            myPlayer.save();
          }

          document.addEventListener('DOMContentLoaded', initGame);
          

The View

  • DOM with CSS
  • Pages or page fragments
  • Easily manipulated
    • swapped and moved around
    • Can be styled or populated with data
  • Can be changed without breaking app

The View


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
</head>
<body>
...

  <section id="profile">
    <p>
      <span id="name">{{ name }}</span>
      <span id="score">{{ score }}</span>
    </p>
  </section>


...
  
  <section id="setting">
          

The View


          function View(id) {
            this.element = document.getElementById(id);
          }

          View.prototype.populate = function(data) {
            Mustache.to_html(this.element, data);
          };

          View.prototype.hide = function() {
            this.element.style.display = 'none';
          };

          document.addEventListener('DOMContentLoaded', function() {
            var myProfile = new View('profile');
            var p = new Player("mike");
            p.addPoints(100);

            myProfile.populate(p);
          });

          

The Controller

  • Glue code
    • decides what data we need
    • decides what to display
    • ties Model to the Views
  • Can be hierarchical
    • main controller (router)
    • page controllers
  • responsible for flow of control
         function Controller(view, model) {
            this.view = view;
            this.model = model;
          }

          Controller.prototype.playGame = function() {
            this.model.restore();
            this.view.populate(this.model);
            this.model.addScore(1000);
            this.endGame();
          };

          Constroller.prototype.endGame = function() {
            this.view.populate(this.model);
            this.model.save();
          };

          var gameController = new Controller(new Player(), new View('profile'));
          gameController.playGame();
          

Router

  • Application Overlord
    • initialization
    • flow of control
    • error handling, sometimes
  • Sometimes just called "App" object
  • Offloads work to sub controllers

Tie it all together

         function Router() {
            this.player = new Player();
            this.profileView = new View('profile');
            this.gameController = new Controller(this.profileView, this.player);
          }

          Router.prototype.route = function(route) {
            if (route === 'play')
              gameController.playGame();
            } else {
              console.log('Unrecognized route');
            }
          };

          document.addEventListener('DOMContentLoaded', function() {
            var myRouter = new Router();
            myRouter.route('play');
          });
          

Best Practices

  1. Don't invent your own
  2. Try out a few
    Backbone
    Angular
    Ember
  3. Use only what you like
  4. Eventually, make your own