Backbone is an amazing Model_View_Controller (MVC)-inspired library that handles data (Model/Collection) synchronization with a RESTful server for Object_Relational_Mapping (ORM), page routing, etc. Unfortunately, their Views become complex to maintain when dynamic Model and View synchronization is required (which is why Knockback exists).
// Model
earth = new Backbone.Model({first_name: 'Planet', last_name: 'Earth'})
mars = new Backbone.Model({first_name: 'Planet', last_name: 'Mars'})
// Collection
planets = new Backbone.Collection([earth, mars])
// Model
var earth = new Backbone.Model({first_name: 'Planet', last_name: 'Earth'});
var mars = new Backbone.Model({first_name: 'Planet', last_name: 'Mars'});
// Collection
var planets = new Backbone.Collection([earth, mars]);
Router:
class PageRouter extends Backbone.Router
routes:
"earth": "switchToEarth" // #earth
"mars": "switchToMars" // #mars
switchToEarth: -> # do something
switchToMars: -> # do something
# instantiate the router and start listening for URL changes
page_router = new PageRouter()
Backbone.history.start()
var PageRouter = Backbone.Router.extend({
routes: {
"earth": "switchToEarth", // #earth
"mars": "switchToMars" // #mars
},
switchToEarth: function() { /* do something */ },
switchToMars: function() { /* do something */ }
});
// instantiate the router and start listening for URL changes
var page_router = new PageRouter()
Backbone.history.start()
Knockout follows the Model_View_ViewModel (MVVM) design pattern meaning you specify a ViewModel (Controller) in addition to your data (Model) which encapsulates specific data and logic for your HTML/Template (View).
<div id='ko_basic'> <p>First name: <input class='input-small pull-right' data-bind="value: first_name, valueUpdate: 'keyup'" /></p> <p>Last name: <input class='input-small pull-right' data-bind="value: last_name, valueUpdate: 'keyup'" /></p> <p>Hello, <span data-bind="text: full_name"> </span>!</p> </div>
model = {first_name: "Planet", last_name: "Earth"}
ViewModel = (model) ->
@first_name = ko.observable(model.first_name)
@last_name = ko.observable(model.last_name)
@full_name = ko.computed((->return "#{@first_name()} #{@last_name()}"), @)
return
view_model = new ViewModel(model)
ko.applyBindings(view_model, $('#ko_basic')[0])
var ko = kb.ko;
var model = {first_name: "Planet", last_name: "Earth"};
var ViewModel = function(model) {
this.first_name = ko.observable(model.first_name);
this.last_name = ko.observable(model.last_name);
this.full_name = ko.computed((function() {return "" + (this.first_name()) + " " + (this.last_name());}), this);
};
var view_model = new ViewModel(model);
ko.applyBindings(view_model, $('#ko_basic')[0]);
First name:
Last name:
Hello, !
In Knockout.js, ViewModels need to be unique instances so often you use a simple function with 'new' to create an instance to bind. Here are some equivalents:
# Form 1: Simple function-based class
ViewModel = (model) ->
@first_name = ko.observable(model.first_name)
return
view_model = new ViewModel({first_name: "Hello"})
# Form 2: CoffeeScript class (allows for inheritance)
class ViewModel
constructor: (model) ->
@first_name = ko.observable(model.first_name)
view_model = new ViewModel({first_name: "Hello"})
// Simple function-based class
var ViewModel = function(model) {
this.first_name = ko.observable(model.first_name);
};
var view_model = new ViewModel({first_name: "Hello"});