Upload
hurlee-lhavagsuren
View
24
Download
0
Tags:
Embed Size (px)
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
minErr - Improved Error Messages[$rootScope:infdig] http://...?p0=10&...
@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?