Play-By-Play Announcer: Todd Bashor todd@TheStartersAcademy.com Image credit: http://www.mobygames.com/images/shots/l/73414-mtv-celebrity-deathmatch-windows-screenshot-title-screens.jpg VS Background image credit: nicksarebi on Flickr VS 3 AGE 3 1.0.0 CURRENT 1.2.0-RC.2 18 RELEASES 55 2753 ISSUES CLOSED 3577 21 ISSUES OPEN 623 19.4KB WEIGHT 81.4KB Round 1: Learnability “…perhaps easy to adopt because it’s so minimal” -Steven Sanderson “The learning curve of AngularJS can be described as a hockey stick.” -Matt Frisbie BACKBONE UP BY 1 Round 2: Separation of Concerns Module Model Sync Collection View Router Events Scope $http, $resource View Directive Filter $routeProvider, $location Controller, $... Round 2: Separation of Concerns View var HelloView = Backbone.View.extend({ template: _.template($('#hello-template').html()), events: {"click button": "doSomething"}, render: function(){ Model $(this.el).html( var Greeting = this.template( Backbone.Model.extend({}); this.model.attributes)); return this; var greeting = new }, Greeting({title: ”World"}); doSomething: function(e){ /*do something*/} DOM }); <script type=“text/template” id=“hello-template”> var helloView = new HelloView({model: greeting}); <p>Hello <%= title %></p> $("body").append(helloView.el); <button>OK</button> helloView.render(); </script> Round 2: Separation of Concerns Image credit: http://docs.angularjs.org/guide/concepts Angular Directive <input todo-blur="doSomething(todo)"> todomvc.directive('todoBlur', function () { return function (scope, elem, attrs) { elem.bind('blur', function () { scope.$apply(attrs.todoBlur); }); }; }); BACKBONE STILL UP BY 1 Round 3: Templating Pick your favorite template engine underscore handlebars dust ejs jade … Decorate the DOM Round 3: Templating <script type="text/template" id="item-template"> <div class="view"> <input class="toggle" type="checkbox” <%= completed ? 'checked': '' %>> <label><%- title %></label> <button class="destroy"></button> </div> <input class="edit" value="<%= title %>"> </script> Round 3: Templating <div class="view"> <input class="toggle" type="checkbox" ng-model="todo.completed"> <label ng-dblclick="editTodo(todo)">{{todo.title}}</label> <button class="destroy" ng-click="removeTodo(todo)"></button> </div> 1 EACH Round 4: Routing var TodoRouter = Backbone.Router.extend({ routes: { '*filter': 'setFilter’ }, setFilter: function (param) {…} }); app.TodoRouter = new TodoRouter(); Backbone.history.start(); Round 4: Routing var todomvc = angular.module('todomvc', []). config(['$routeProvider', function($routeProvider) { $routeProvider .when('/:state', { templateUrl: 'index.html', controller: todomvc.TodoCtrl }) .otherwise({redirectTo: '/'}); }]); <div ng-view></div> BACKBONE UP BY 1 Round 5: Testability beforeEach(function () { this.model = new app.Todo(); this.view = new app.TodoView({ model: this.model }); }); Round 5: Testability it("should set focus for editing", function () { // Must call render to populate element for // `$input` this.view.render(); var spy = sinon.spy(this.view.$input, "focus"); this.view.edit(); expect(spy).to.be.calledOnce; }); Round 5: Testability /*global inject, expect, angular*/ describe('todoFocus directive', function () { var scope, compile, browser; beforeEach(inject( function ($rootScope, $compile, $browser) { scope = $rootScope.$new(); compile = $compile; browser = $browser; })); //snip }); Round 5: Testability describe('SetFocus directive', function() { var scope, element, timeout; beforeEach(inject(function($rootScope, $compile, $timeout) { timeout = $timeout; scope = $rootScope.$new(); element = angular.element('<input set-focus="inFocus" />'); $compile(element)(scope); scope.$digest(); })); it('sets the input to be focussed when inFocus message is broadcast', function() { scope.$broadcast('inFocus'); timeout.flush(); expect(scope.focusedElement).toEqual(element); }); }); 2 EACH Round 6: Reusability Plugins Directives Filters Services ANGULAR UP BY 1 Round 7: Community 192 CONTRIBUTO RS 397 1,268 WATCHERS 1,577 15,810 STARS 14,842 29,181 STACKOVERFLO W 34,295 76 BOOKS 55 TIED! 3 ROUNDS EACH Round 8: Fit for Purpose Fix your jQuery Take HTML to a new level Enhance your page Build serious CRUD apps Play well with other libraries Maintain large apps Learn More backbonejs.org todomvc.com backbonetutorials.com github.com/addyosmani/backbonefundamentals angularjs.org todomvc.com egghead.io github.com/jmcunningham/Angular JS-Learning Todd Bashor todd@TheStartersAcademy.com