GDI Logo

JavaScript MVC

teaching-materials.org/jsmvc/

JavaScript and Websites

A brief history

Web 1.0: JS for Almost Nothing

Web 2.0: JS for AJAX

Web Today: JS for Everything

Big JS Web Apps

What does the JS do?

  • Fetches data (via AJAX)
  • Processes and calculates data
  • Creates DOM (like w/jQuery)
  • Reacts to events

...that's a lot of JS.



Coursera: 28,848 lines of JS code..

Let's make it manageable



  • Split into multiple files.
  • Modularize the code into re-usable chunks.
  • Use object-oriented concepts to organize code.
  • Separate the code into "model" vs. "view"

Model vs. View

"Model"

(Data)

Fetch data

Process data

"View"

(Presentation)

Create DOM

Handle DOM Events

Example: BookShelf App

Try It!

  Model:  View:

The Book Model

Simple version: stores properties passed in

var BookModel = function(bookJSON) {
  this.title     = bookJSON.title;
  this.author    = bookJSON.author;
  this.asin      = bookJSON.asin;
  this.thumbnail = bookJSON.thumbnail;
  this.rating    = bookJSON.rating;
  this.review    = bookJSON.review;
};
var book = new BookModel({
    title: "1984",
    author: "George Orwell",
    asin: "0451524934",
    thumbnail: "http://images.amazon.com/images/P/0451524934.01.ZTZZZZZZ.jpg",
    rating: 4
  });

The Book Model

Better: Sets defaults for properties

var BookModel = function(bookJSON) {
  this.title     = bookJSON.title || 'Untitled';
  this.author    = bookJSON.author || 'Unknown author';
  this.asin      = bookJSON.asin;
  this.thumbnail = bookJSON.thumbnail;
  this.rating    = bookJSON.rating;
  this.review    = bookJSON.review || '';
};
var book = new BookModel({
    asin: "0451524934",
    thumbnail: "http://images.amazon.com/images/P/0451524934.01.ZTZZZZZZ.jpg",
    rating: 4
  });

The Book Model

Even better: computes properties

var BookModel = function(bookJSON) {
  this.title     = bookJSON.title || 'Untitled';
  this.author    = bookJSON.author || 'Unknown author';
  this.asin      = bookJSON.asin;
  this.thumbnail = bookJSON.thumbnail;
  this.rating    = bookJSON.rating;
  this.review    = bookJSON.review || '';
  this.url       = 'http://www.amazon.com/gp/product/'
      + this.asin + '?tag=amazonsimilar-20';
};
var book = new BookModel({
    title: "1984",
    author: "George Orwell",
    asin: "0451524934",
    thumbnail: "http://images.amazon.com/images/P/0451524934.01.ZTZZZZZZ.jpg",
    rating: 4
  });

The BookCollection

Creates an array of Models and provides sorts.

var BookCollection = function(booksJSON) {
  this.items = [];
  for (var i = 0; i < booksJSON.length; i++) {
    this.items.push(new BookModel(booksJSON[i]));
  }
};

BookCollection.prototype.sort = function() {
  this.items.sort(function(bookA, bookB){
    return (bookA.rating - bookB.rating);
  });
};
  
var booksJSON = [{
    title: "1984",
    author: "George Orwell",
    asin: "0451524934",
    thumbnail: "http://images.amazon.com/images/P/0451524934.01.ZTZZZZZZ.jpg",
    rating: 4
  }]

var books = new BookCollection(booksJSON);

Exercise Time!

A BookShelf View

var BookShelfView = function(books) {
  var shelfDiv = $('<div>');
  for (var i = 0; i < books.items.length; i++) {
    var book = books.items[i];
    // Create a div with a linked image inside it, 
    // and add that to the shelf div
    var bookDiv = $('<div class="book">');
    var bookLink = $('<a>');
    bookLink.attr('href', book.url);
    var bookCover = $('<img>');
    bookCover.attr('src', book.thumbnail);
    bookLink.append(bookCover);
    bookDiv.append(bookLink);

    shelfDiv.append(bookDiv);

    // On mouseover, pop up the review
    bookDiv.bind('mouseover', function(e) {
        var reviewDiv = $('<div class="book-review">');
        reviewDiv.html('<strong>' + book.rating + ' stars: </strong>' + (book.review || ' No review.'));
        reviewDiv.css({'position': 'absolute', 'top':  e.pageY, 'left': e.pageX});
        $('body').append(reviewDiv);
    });
    bookDiv.bind('mouseout', function() {
      $('.book-review').remove();
    });
  }
  return shelfDiv;
};
  

Smaller/Nested Views

var BookView = function(book) {
  var bookDiv = $('<div class="book">');
  var bookLink = $('<a>');
  bookLink.attr('href', book.url);
  var bookCover = $('<img>');
  bookCover.attr('src', book.thumbnail);
  bookLink.append(bookCover);
  bookDiv.append(bookLink);

  // Attach event listeners
  return bookDiv;
};

var BookShelfView = function(books) {
  var shelfDiv = $('<div>');
  for (var i = 0; i < books.items.length; i++) {
    var book = books.items[i];
    shelfDiv.append(new BookView(book));
  }
  return shelfDiv;
};
  

BookShelf App:
MVC Version

Try it!

Exercise Time!

MV* Frameworks

MV* Frameworks



Journey through the JS MVC Jungle, TodoMVC