100
@angularjs #DV13-NGU AngularJS End to End Brad Green Brian Ford Miško Hevery Igor Minar

Angular University Devoxx 2013.pptx

Embed Size (px)

Citation preview

Page 1: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

AngularJS End to End

Brad Green Brian Ford Miško Hevery Igor Minar

Page 2: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Building your First App(basic concepts)

Brad Green@bradlygreen

Page 3: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Setup: Template

<html ng-app='coolApp'>…<body>… <script src='angular.js'></script> <script src='coolApp.js'></script></body></html>

Page 4: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Setup: JS

var myApp = angular.module('coolApp', []);

Page 5: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Principles

Boilerplate

D.R.Y. StructureTestabilit

y

Page 6: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

ManagesNotifies

Observes

Controller(JS Classes)

View(DOM)

RAM

Model(JS

Objects)

<div>

<span> <ul>

<li>

Structure: Model-View-Controller

Page 7: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

{ "name": "Misko" }

<p ng-controller='PersonController as person'>

Hi, {{person.model.name}}

</p>

myApp.controller('PersonController', function () {

this.model = { name: 'Misko' };

});

Model:

View:

Controller:

Page 8: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

{ "name": "Misko" }

<p ng-controller='PersonController as person'>

Hi, {{person.model.name}}

</p>

myApp.controller('PersonController', function (s) {

this.model = s.getPerson();

});

Model:

View:

Controller:

Page 9: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Feature: Data Binding

this.greeting = 'Hola!';

{{ greeter.greeting }} // 1-way

<input ng-model='greeter.greeting'> // 2-way

hello.html

hello.js

Page 10: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Note: Binding for initial page load

<p>{{someObj.something}}</p>

Markup fine except for first page

<p ng-bind='someObj.something'></p>

Attribute form also avoid unstyled content on load

<p ng-cloak>{{someObj.something}}</p>

Use ng-cloak to avoid unstyled content on load

Page 11: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Feature: Directives

<div ng-repeat='item in cart.items'> <span ng-bind='item.name'></span> <button ng-click='cart.delete($index)'> Delete </button></div>

Page 12: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Note: Directive validation

<div data-ng-repeat='item in cart.items'> <span data-ng-bind='item.name'></span> <button data-ng-click='cart.delete($index)'> Delete </button></div>

Page 13: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Feature: Dependency Injection

function MyFoo() { … };module.service('foo', MyFoo);

function MyBar(foo) { Foo instanceof MyFoo; // true! }

Definition

Usage

Page 14: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Preferred usage

myApp.service('foo', function() { ...});

Page 15: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Principle: Eliminate boilerplate

Dependency Injection

POJO Models

No DOM in most code paths

Page 16: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

View Templates

Directives

Markup {{ }}

Form Validation

Filters

Page 17: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Filters

<p>{{ invoice.total | currency }}</p>

Page 18: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Filter example: Reverse

myApp.filter('reverse', function() {

return function(input) {

var out = '';

for (var i = 0; i < input.length; i++) {

out = input.charAt(i) + out;

}

return out;

}

});

Page 19: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Back to ControllersThus far:● Expose model to view● Expose functions to handle user interaction ● Update model to change the view

But also:● Instantiated once per use in your template● Can request $scope

Page 20: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

$scope

myApp.controller('GreetCtrl', function ($scope) {

$scope.greeter = { greeting: 'Misko'};

});

<p ng-controller='GreetCtrl'>{{greeter.greeting}}</p>

You can request $scope in controllers

Use in template

Page 21: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

$scope

Context for expression evaluation

Hierarchical, mirroring your DOM structure

Prototypal inheritance = global read, local write

Page 22: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

$scope$watch(expression, callback): Executes a callback whenever a given expression changes$apply() : synchronize data binding from outside Angular's event loop

Page 23: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expressions

{{ The stuff inside your markup }}

ng-bind='and inside directives'

Like JavaScript, but eval'd against your $scope

No complex logic like loops or throws

Though terinary operator is supported

Page 24: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expression Examples

person.name

shoppingCart.total()

cart.total() - user.discountRate

Page 25: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Talking to servers

$http: HTTP server communication$resource: RESTful server communicationNotable other options: ● Restangular● AngularFire● BreezeJS

Page 26: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

$http

this.someData = $http.get('/someUrl');

Page 27: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

$http

$http.get('/someUrl').

success(function(data, status, headers, config) {

// called asynchronously

}).

error(function(data, status, headers, config) {

// called if an error occurs, also async

});

Page 28: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Promises

$http.post('/user/', user).then( function() { alert('Successfully created user!'); }, function() { alert('Error creating user...'); });

Page 29: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Routes

HeaderLe

ft N

av

Content View

Page 30: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Routes

<ng-view> directive as content placeholder

$routeProvider to configure:● Controller● Template● URL

Page 31: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Routes

myApp.config(function($routeProvider) {

$routeProvider.when('/inbox', {

templateUrl: 'inbox.html',

controller: 'InboxCtrl',

controllerAs: 'inbox'

});

});

Page 32: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Putting it all together

Page 33: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

ResourcesUI Components

Bootstrap

LibrariesTools

Batarang

Books

Page 34: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Learning Resources

egghead.io thinkster.io pluralsight.comdocs.angularjs.org/tutorial

Page 35: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Questions?

Page 36: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Internals of AngularJS(How it all works)

Miško Hevery

Page 37: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Data Binding

Goal: Separate code from HTML

Page 38: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Data Binding

Drives

<div>

<span> <ul>

<li><li><li>

Model

Depends on

<div>

<span> <ul>

<li><li><li>

Model

Page 39: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Data Binding: Requirements

•Model is a Plain-Old-JavaScript-Object•Detect value changes•Easily describe value in the model•Encapsulate DOM access

Page 40: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Scope

Goal: Provide context for expressions

Page 41: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Scope

User = function () {

this.fullName = 'Miško Hevery';

this.username = 'mhevery';

}

scope = {};

scope.user = new User();

{{user.fullName}}

{{user.username}}

Page 42: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Scope

{{name}}

<ul>

<li ng-repeat="name in names">

{{name}}

</li>

</ul>

Page 43: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Scope

parent = {};

child = inherit(parent);

parent.name = 'parent';

expect(child.name).toEqual('parent');

child.name = 'child');

expect(child.name).toEqual('child');

expect(parent.name).toEqual('parent');

Page 44: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Scope

function inherit(parent) {

function C() {}

C.prototype = parent;

return new C();

}

parent = {};

child = inherit(parent);

expect(child.__proto__).toBe(parent);

Page 45: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

{{name}}

<ul>

</ul>

Scope

<li ng-repeat="name in names">

{{name}}

</li>

Page 46: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Watchers

Goal: Notify of model changes

Page 47: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Watchers

{{name}}

scope.name = 'Miško Hevery';

scope.$watch('name', function(value) {

element.text(value);

});

Page 48: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle

Goal: Non-intrusive change detection

Page 49: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle

scope.$watch('name', reactionFn);

var lastValue;

function dirtyCheck() {

var value = scope.name;

if (lastValue != value) reactionFn(value);

lastValue = value;

}

Page 50: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle

scope.$watch('count', function(value) {

alert(value);

});

scope.$watch('name', function(value) {

scope.count++;

});

Page 51: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle

Goal: Knowing when to digest

Page 52: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle

Page 53: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle: Sync vs Async

var result1 = cacheApi(function() {

result1.doSomething();

});

• API should not mix sync/async• Need a way to simulate async callbacks• setTimeout(0) is problematic

Page 54: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Digest Cycle: Sync vs Async

StackFrame

#3 asyncApi()

#2 yourApplicationBehavior()

#1 ng.$apply()

#0 nativeCode(event)

Page 55: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expressions

Goal: Code of least surprise

Page 56: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expressions

{{user.firstName}}

eval('with(scope){return user.firstName;}');

if (scope.user) {

return scope.user.firstName;

}

Page 57: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expressions

•eval() can not be the solution•silent dereference•executes in global context•CSP•Security

Page 58: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Expressions

•Let's think out of the box•Let's implement JavaScript in JavaScript•Full lexer and parser implies full control over:

•Syntax•Semantics

Page 59: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Directive

Goal: Express intent in HTML

Page 60: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Directive

<ul>

<li ng-repeat="user in users">

{{user.name}}

</li>

</ul>

Page 61: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Directive

scope.$watch('name', function(value) {

element.text(value);

});

<span ng-bind="name"></span>

Page 62: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Compiler

Goal: extend HTML syntax(teach browser new tricks)

Page 63: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Compiler

<div ng-controller="MyCtrl as c">

<div ng-repeat="name in c.names">

{{name}}</div>

</div>

• Traverse the DOM => locate directives, remember location• Template: Easily apply directives to DOM clone

Page 64: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

Goal: Get rid of setup code

Page 65: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

function Door() {}

function House(door) {}

function App(house) {}

// implied

app = new App(new House(new Door)));

Page 66: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

How do you know what to inject?

Page 67: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

function Door() {}

function House(door) {}

House.$inject = ['door'];

function App(house) {}

App.$inject = ['house'];

Page 68: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

describe('something', function() {

function test($rootScope){}

test.$inject = ['$rootScope'];

it('should ...', test);

});

Page 69: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

function House(door) {}

House.$inject =

creazyRegExp(House.toString());

Page 70: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

function Door(){}

function House(door) {}

injector = new Injector(...);

house = injector.instantiate(House);

Page 71: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

function instantiate(Type) {

var args = Type.$inject.map(instantiate);

return new Type.call(args);

}

Page 72: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Dependency Injection

Add Caching, Modules and some syntactic sugar and

you have full DI system

Page 73: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Routing

Goal: Preserve the web paradigm

Page 74: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

•Deep linking•Links work like links•Support HTML5 pushstate•URL rewriting

Routing

Page 75: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

<a href="/chapter/{{id}}">

http://server.com/chapter/123http://server.com/#!/chapter/123

Routing

•Server cooperation needed

Page 76: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

REST

Goal: Easy server communication

Page 77: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

REST

•Make common case simple•Take advantage of data-binding•Future / Promises

Page 78: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

REST

Chapter = $resource('/chapter/:chapterId');

var chapters = Chapter.query();

<div ng-repeat="chapter in chapters"> {{chapter.name}}</div>

Page 79: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Questions?

Page 80: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

The New Stuff(animations, track by, controller as,

security, error messages)Brian Ford and Igor Minar

Page 81: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animations in Angular

Animations are a natural extension of CSS3

animations and AngularJS directives

Page 82: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animations in Angular

Angular automatically coordinates DOM operations, so you can focus on

the visuals of the animation.

Page 83: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animations// HTML

<div ng-repeat="item in list" class="item">{{item}}</div>

//CSS.item.ng-leave {

animation: 0.5s my_animation;

}

@keyframes my_animation {

from { opacity:1; }

to { opacity:0; }

}

.item.ng-enter, .item.ng-move {

transition:0.5s linear all;

opacity: 0;

}

.item.ng-enter.ng-enter-active,

.item.ng-move.ng-move-active {

opacity: 1;

}

Page 84: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation Hooks

http://docs.angularjs.org/guide/animations

Page 85: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation in Action

Example App: https://github.com/matsko/ngconf-animations-demo

Page 86: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation (& Touch) in Action

Example: Sidebar

● ngIf● ngSwipeLeft/Right

https://github.com/btford/brian-talks-about-animations

Page 87: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation in Action

Example: Slideshow

● ngView

https://github.com/btford/brian-talks-about-animations

Page 88: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation in Action

Example: Notifications

● ngRepeat

https://github.com/btford/brian-talks-about-animations

Page 89: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation Best Practices

With great power comes great responsibility

● Be tasteful○ use sparingly

● They should enhance UX○ same functionality, but better affordances

● Keep them fast○ http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

Page 90: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Animation and track by (ng-repeat)

•ng-repeat is stable•Database data needs to be refreshed

<div ng-repeater="o in objs track by o.id">

...

</div>

Page 91: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

"Controller As"

Before:

<div ng-controller="UserController">

<p>{{name}}</p>

<div ng-if="someCondition"> <input ng-model="name">

</div>

</div>

Page 92: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

"Controller As"

Unambiguously bind to models:<div ng-controller="UserController as user">

<p>{{user.name}}</p>

<div ng-if="someCondition"> <input ng-model="user.name">

</div>

</div>

Page 93: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Security Enhancements

● Template origin verification● Expression sandbox hardening● Better Content Security Policy support● SCE

Page 94: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

SCE (strict contextual auto-escaping)

<input ng-model="userHtml">

<div ng-bind-html="userHtml">

Page 95: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

SCE (strict contextual auto-escaping)

var htmlSrc = '<div>...</div>';

var htmlWrapper = $sce.trustAsHtml(htmlSrc);

var htmlDst = $sce.getTrustedHtml(htmlWrapper);

Page 96: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Improved Error MessagesBefore:Uncaught Error: No module: ngResource

After:Uncaught Error: [di-nomod] Module 'ngResource' is not available! You either misspelled the module name or forgot to load it.http://docs.angularjs.org/error/di-nomod?a=ngResourceIn production:Uncaught Error: [di-nomod] ngResourcehttp://docs.angularjs.org/error/di-nomod?a=ngResource

Page 98: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

More Angular!

Between 1.0.0 and 1.2.0 ...•1,575 SHAs/PRs•2,850 Issues closed

Directory LOC Added LOC Removed LOC Total

* 101,489 36,938

/src 37,572 10,801 52,957

Page 99: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Even Moar Angular!What Where When

Advanced AngularJS Workshop

BOF1 Mon 13:30 - 16:30

Unit testing JavaScript / CoffeeScript / Dart code with Karma

Room 8 Tue 17:25 - 17:55

AngularJS Meetup BOF1 Wed 19:00 - 20:00

Future of Angular Room 9 Thu 12:00 - 13:00

Page 100: Angular University Devoxx 2013.pptx

@angularjs#DV13-NGU

Questions?