Angular University Devoxx 2013.pptx

Preview:

Citation preview

@angularjs#DV13-NGU

AngularJS End to End

Brad Green Brian Ford Miško Hevery Igor Minar

@angularjs#DV13-NGU

Building your First App(basic concepts)

Brad Green@bradlygreen

@angularjs#DV13-NGU

Setup: Template

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

@angularjs#DV13-NGU

Setup: JS

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

@angularjs#DV13-NGU

Principles

Boilerplate

D.R.Y. StructureTestabilit

y

@angularjs#DV13-NGU

ManagesNotifies

Observes

Controller(JS Classes)

View(DOM)

RAM

Model(JS

Objects)

<div>

<span> <ul>

<li>

Structure: Model-View-Controller

@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:

@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:

@angularjs#DV13-NGU

Feature: Data Binding

this.greeting = 'Hola!';

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

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

hello.html

hello.js

@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

@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>

@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>

@angularjs#DV13-NGU

Feature: Dependency Injection

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

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

Definition

Usage

@angularjs#DV13-NGU

Preferred usage

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

@angularjs#DV13-NGU

Principle: Eliminate boilerplate

Dependency Injection

POJO Models

No DOM in most code paths

@angularjs#DV13-NGU

View Templates

Directives

Markup {{ }}

Form Validation

Filters

@angularjs#DV13-NGU

Filters

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

@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;

}

});

@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

@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

@angularjs#DV13-NGU

$scope

Context for expression evaluation

Hierarchical, mirroring your DOM structure

Prototypal inheritance = global read, local write

@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

@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

@angularjs#DV13-NGU

Expression Examples

person.name

shoppingCart.total()

cart.total() - user.discountRate

@angularjs#DV13-NGU

Talking to servers

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

@angularjs#DV13-NGU

$http

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

@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

});

@angularjs#DV13-NGU

Promises

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

@angularjs#DV13-NGU

Routes

HeaderLe

ft N

av

Content View

@angularjs#DV13-NGU

Routes

<ng-view> directive as content placeholder

$routeProvider to configure:● Controller● Template● URL

@angularjs#DV13-NGU

Routes

myApp.config(function($routeProvider) {

$routeProvider.when('/inbox', {

templateUrl: 'inbox.html',

controller: 'InboxCtrl',

controllerAs: 'inbox'

});

});

@angularjs#DV13-NGU

Putting it all together

@angularjs#DV13-NGU

ResourcesUI Components

Bootstrap

LibrariesTools

Batarang

Books

@angularjs#DV13-NGU

Learning Resources

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

@angularjs#DV13-NGU

Questions?

@angularjs#DV13-NGU

Internals of AngularJS(How it all works)

Miško Hevery

@angularjs#DV13-NGU

Data Binding

Goal: Separate code from HTML

@angularjs#DV13-NGU

Data Binding

Drives

<div>

<span> <ul>

<li><li><li>

Model

Depends on

<div>

<span> <ul>

<li><li><li>

Model

@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

@angularjs#DV13-NGU

Scope

Goal: Provide context for expressions

@angularjs#DV13-NGU

Scope

User = function () {

this.fullName = 'Miško Hevery';

this.username = 'mhevery';

}

scope = {};

scope.user = new User();

{{user.fullName}}

{{user.username}}

@angularjs#DV13-NGU

Scope

{{name}}

<ul>

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

{{name}}

</li>

</ul>

@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');

@angularjs#DV13-NGU

Scope

function inherit(parent) {

function C() {}

C.prototype = parent;

return new C();

}

parent = {};

child = inherit(parent);

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

@angularjs#DV13-NGU

{{name}}

<ul>

</ul>

Scope

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

{{name}}

</li>

@angularjs#DV13-NGU

Watchers

Goal: Notify of model changes

@angularjs#DV13-NGU

Watchers

{{name}}

scope.name = 'Miško Hevery';

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

element.text(value);

});

@angularjs#DV13-NGU

Digest Cycle

Goal: Non-intrusive change detection

@angularjs#DV13-NGU

Digest Cycle

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

var lastValue;

function dirtyCheck() {

var value = scope.name;

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

lastValue = value;

}

@angularjs#DV13-NGU

Digest Cycle

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

alert(value);

});

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

scope.count++;

});

@angularjs#DV13-NGU

Digest Cycle

Goal: Knowing when to digest

@angularjs#DV13-NGU

Digest Cycle

@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

@angularjs#DV13-NGU

Digest Cycle: Sync vs Async

StackFrame

#3 asyncApi()

#2 yourApplicationBehavior()

#1 ng.$apply()

#0 nativeCode(event)

@angularjs#DV13-NGU

Expressions

Goal: Code of least surprise

@angularjs#DV13-NGU

Expressions

{{user.firstName}}

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

if (scope.user) {

return scope.user.firstName;

}

@angularjs#DV13-NGU

Expressions

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

@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

@angularjs#DV13-NGU

Directive

Goal: Express intent in HTML

@angularjs#DV13-NGU

Directive

<ul>

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

{{user.name}}

</li>

</ul>

@angularjs#DV13-NGU

Directive

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

element.text(value);

});

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

@angularjs#DV13-NGU

Compiler

Goal: extend HTML syntax(teach browser new tricks)

@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

@angularjs#DV13-NGU

Dependency Injection

Goal: Get rid of setup code

@angularjs#DV13-NGU

Dependency Injection

function Door() {}

function House(door) {}

function App(house) {}

// implied

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

@angularjs#DV13-NGU

Dependency Injection

How do you know what to inject?

@angularjs#DV13-NGU

Dependency Injection

function Door() {}

function House(door) {}

House.$inject = ['door'];

function App(house) {}

App.$inject = ['house'];

@angularjs#DV13-NGU

Dependency Injection

describe('something', function() {

function test($rootScope){}

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

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

});

@angularjs#DV13-NGU

Dependency Injection

function House(door) {}

House.$inject =

creazyRegExp(House.toString());

@angularjs#DV13-NGU

Dependency Injection

function Door(){}

function House(door) {}

injector = new Injector(...);

house = injector.instantiate(House);

@angularjs#DV13-NGU

Dependency Injection

function instantiate(Type) {

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

return new Type.call(args);

}

@angularjs#DV13-NGU

Dependency Injection

Add Caching, Modules and some syntactic sugar and

you have full DI system

@angularjs#DV13-NGU

Routing

Goal: Preserve the web paradigm

@angularjs#DV13-NGU

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

Routing

@angularjs#DV13-NGU

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

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

Routing

•Server cooperation needed

@angularjs#DV13-NGU

REST

Goal: Easy server communication

@angularjs#DV13-NGU

REST

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

@angularjs#DV13-NGU

REST

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

var chapters = Chapter.query();

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

@angularjs#DV13-NGU

Questions?

@angularjs#DV13-NGU

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

security, error messages)Brian Ford and Igor Minar

@angularjs#DV13-NGU

Animations in Angular

Animations are a natural extension of CSS3

animations and AngularJS directives

@angularjs#DV13-NGU

Animations in Angular

Angular automatically coordinates DOM operations, so you can focus on

the visuals of the animation.

@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;

}

@angularjs#DV13-NGU

Animation Hooks

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

@angularjs#DV13-NGU

Animation in Action

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

@angularjs#DV13-NGU

Animation (& Touch) in Action

Example: Sidebar

● ngIf● ngSwipeLeft/Right

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

@angularjs#DV13-NGU

Animation in Action

Example: Slideshow

● ngView

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

@angularjs#DV13-NGU

Animation in Action

Example: Notifications

● ngRepeat

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

@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/

@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>

@angularjs#DV13-NGU

"Controller As"

Before:

<div ng-controller="UserController">

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

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

</div>

</div>

@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>

@angularjs#DV13-NGU

Security Enhancements

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

@angularjs#DV13-NGU

SCE (strict contextual auto-escaping)

<input ng-model="userHtml">

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

@angularjs#DV13-NGU

SCE (strict contextual auto-escaping)

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

var htmlWrapper = $sce.trustAsHtml(htmlSrc);

var htmlDst = $sce.getTrustedHtml(htmlWrapper);

@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

@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

@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

@angularjs#DV13-NGU

Questions?