Ember vs. Angular – Javascript.io; March 6, 2014 – Who's using this stuff?



Ember vs. Angular – Javascript.io; March 6, 2014 – Who's using this stuff?

0 0


ember-angular-presentation

A presentation comparing/contrasting Ember.js and AngularJS.

On Github minznerjosh / ember-angular-presentation

Ember vs. Angular

Javascript.io; March 6, 2014

Who Is This?

  • First JS Exposure in Middle School
  • Messed with PHP, JQuery, Objective-C
  • Cappuccino, SproutCore, Ember.js

Now

Software Engineer @ Cinema6

Cinema6

Browser apps, online video, AngularJS.

So, what are AngularJS and Ember.js?

  • Browser is more than a document viewer
  • Browser is an application runtime environment
  • Ember and Angular help you create browser apps

Who's using this stuff?

AngularJS

Ember.js

Similarities

Two-Way Data Binding

AngularJS

index.html
                            
<body ng-app>
    <h4>My title: {{title}}</h4>
    <form action="">
        <input type="text" ng-model="title">
    </form>
</body>
                            
                        

Ember.js

app.js
                            
var App = Ember.Application.create();
                            
                        
application.hbs
                            
<h4>My Title: {{title}}</h4>
<form action="">
    {{input value=title}}
</form>
                            
                        

Differences

Binding Implementation

AngularJS

  • $scope (the magic)
  • native javascript setters ($scope.model.name = 'Josh';)
  • $scope.digest() (the magic behind the magic)
  • Dirty checking!
index.html
                            
<body ng-app ng-controller="AppController as AppCtrl">
    <h4>What's up, {{name}}?</h4>
    <button ng-click="AppCtrl.sayName('Josh')">Say My Name</button>
</body>
                            
                        
app.js
                            
function AppController($scope) {
    $scope.name = 'Nobody';

    this.sayName = function(name) {
        $scope.name = name;
    }
}
                            
                        

Ember.js

  • Controllers!
  • Setter/Getter Functions (this.set('name', 'Josh');)
  • The run loop.
application.hbs
                            
<h4>What's up, {{name}}?</h4>
<button {{action "sayName" "Josh"}}>Say My Name</button>
                            
                        
app.js
                            
var App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
    name: 'Nobody',
    actions: {
        sayName: function(name) {
            this.set('name', name);
        }
    }
});
                            
                        

What Does This Mean for You?

Performance!

AngularJS

index.html
                            
<body ng-app ng-controller="AppController as AppCtrl">
    <h4>My Title: {{title}}</h4>
    <form action="">
        <input type="text" ng-model="title">
    </form>
    <ul class="list-of-bs">
        <li ng-repeat="model in list">{{model.value}}</li>
    </ul>
    <button ng-click="AppCtrl.upset()">GO NUTS!</button>
    <button ng-click="list.length = 0">Clean Up</button>
</body>
                            
                        
app.js
                            
function AppController($scope) {
    $scope.list = [];

    this.upset = function() {
        for (var index = 0; index < 20000; index++) {
            $scope.list.push({
                value: index
            });
        }
    };
}
                            
                        

Ember.js

application.hbs
                            
<h4>My Title: {{title}}</h4>
<form action="">
    {{input value=title}}
</form>
<ul class="list-of-bs">
    {{#each list}}
        <li>{{this.value}}</li>
    {{/each}}
</ul>
<button {{action "upset"}}>GO NUTS!</button>
<button {{action "cleanUp"}}>Clean Up</button>
                            
                        
app.js
                            
var App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
    list: [],
    actions: {
        upset: function() {
            for (var index = 0; index < 20000; index++) {
                this.list.pushObject({
                    value: index
                });
            }
        },
        cleanUp: function() {
            this.list.clear();
        }
    }
});
                            
                        

Similarities

Philosophy

  • Two-way databinding is great!
  • HTML & CSS belong in Browser App Development

Differences

Philosophy

AngularJS

AngularJS is a toolset for building the framework most suited to your application development.

Ember.js

A framework for building ambitious web applications

Differences

Focus

AngularJS

  • Dependency Injection
  • Testing
  • Composable Views
  • POJO Model

Ember.js

  • URL Routing
  • MVC+R
  • Elimination of Boilerplate (Object Generation)
  • Custom Object Model (Classical Inheritance)

Dependency Injection

AngularJS

                            
angular.module('app', [])
    .service('Useless', function($timeout) {
        this.dumb = function() {
            $timeout(function() {
                alert('TROLL');
            }, 1000);
        }
    })
    .controller('AppController', function(Useless) {
        this.doSomethingDumb = function() {
            Useless.dumb();
        };
    });
                            
                        

Ember.js

                            
var Useless = Ember.Object.extend({
    dumb: function() {
        Ember.run.later(null, function() {
            alert('TROLL');
        }, 1000);
    }
});
Ember.Application.initializer({
    name: 'registerDep',
    initialize: function(container, application) {
        application.register('service:dumb', Useless);
    }
});
Ember.Application.initializer({
    name: 'injectDep',
    after: 'registerDep',
    initialize: function(container, application) {
        application.inject('controller:application', 'useless', 'service:dumb');
    }
});
var ApplicationController = Ember.Controller.extend({
    doSomethingDumb: function() {
        this.useless.dumb();
    }
});
                            
                        

Testing

AngularJS

                            
describe('AppController', function() {
    var $rootScope,
        $scope,
        $controller,
        AppCtrl;

    var Useless;

    beforeEach(function() {
        module('app', function($provide) {
            $provide.value('Useless', {
                dumb: jasmine.createSpy()
            });
        });

        inject(function($injector) {
            $rootScope = $injector.get('$rootScope');
            $controller = $injector.get('$controller');

            Useless = $injector.get('Useless');

            $scope = $rootScope.$new();
            AppCtrl = $controller('AppController', { $scope: $scope });
        });
    });

    it('should call dumb() on Useless when its doSomethingDumb() method is called', function() {
        AppCtrl.doSomethingDumb();
        expect(Useless.dumb).toHaveBeenCalled();
    });
});
                            
                        

Ember.js

                            
describe('AppController', function() {
    var appCtrl;

    var useless;

    beforeEach(function() {
        useless = {
            dumb: jasmine.createSpy()
        };

        appCtrl = App.ApplicationController.create({
            useless: useless
        });
    });

    it('should call dumb() on Useless when its doSomethingDumb() method is called', function() {
        appCtrl.doSomethingDumb();
        expect(useless.dumb).toHaveBeenCalled();
    });
});
                            
                        

Composable Views

AngularJS

                            
<body ng-app="app">
    <h3>{{title}}</h3>
    <blink ng-click="title = 'foo'">Hello!</blink>
</body>
                            
                        
                            
angular.module('app', [])
    .directive('blink', function($timeout) {
        return {
            restrict: 'E',
            scope: {},
            link: function(scope, element) {
                function show() {
                    element.css('display', '');
                    $timeout(hide, 1000);
                }

                function hide() {
                    element.css('display', 'none');
                    $timeout(show, 1000);
                }

                show();
            }
        };
    });
                            
                        

Ember.js

                            
<!-- application.hbs -->
{{#io-blink}}Hello!{{/io-blink}}

<!-- components/io-blink.hbs -->
{{yield}}
                            
                        
                            
var App = Ember.Application.create();
App.IoBlinkComponent = Ember.Component.extend({
    show: function() {
        this.$().show();
        Ember.run.later(this, this.hide, 1000);
    }.on('didInsertElement'),
    hide: function() {
        this.$().hide();
        Ember.run.later(this, this.show, 1000);
    }
});
                            
                        

URL Routing

AngularJS

                            
angular.module('app', ['ngRoute'])
    .config(function($routeProvider) {
        $routeProvider
            .when('/', {
                controller: 'IndexController',
                controllerAs: 'IndexCtrl',
                templateUrl: 'views/index.html'
            })
            .when('/posts', {
                controller: 'PostsController',
                controllerAs: 'PostsCtrl',
                templateUrl: 'views/posts.html'
            });
    });
                            
                        
                            
<h1>My App</h1>
<ng-view></ng-view>
                            
                        

Ember.js

                            
var App = Ember.Application.create();
App.Router.map(function() {
    // /posts
    this.resource('posts', function() {
        // /posts/new
        this.route('new');
    });
});
                            
                        
                            
<!-- application.hbs -->
<h1>My App</h1>
{{outlet}}

<!-- posts.hbs -->
<h1>My Posts</h1>
{{outlet}}

<!-- posts/new.hbs -->
<h1>New Post</h1>
                            
                        

So... Angular or Ember?

That's up to you!

Do you want to spend your time building the framework, or learning the framework?

Fin

Questions?