Angular 2 Core
Igor Minar
Tobias Bosch
ng-europe 2014
AngularJS 1.3
<div ng-controller="SantaTodoController">
<input type="text" ng-model="newTodoTitle">
<button ng-click="addTodo()">+</button>
<tab-container>
<tab-pane title="Tobias">
<div ng-repeat="todo in todosOf('tobias')">
<input type="checkbox"
ng-model="todo.done">
{{todo.title}}
<button ng-click="deleteTodo(todo)">
X
</button>
</div>
</tab-pane>
...
AngularJS 2.0
<div>� <input type="text" [value]="newTodoTitle">� <button (click)="addTodo()">+</buton>�� <tab-container>� <tab-pane title="Good kids">� <div [ng-repeat|todo]="todosOf('good')">� <input type="checkbox"
[checked]="todo.done">� {{todo.title}}� <button (click)="deleteTodo(todo)">
X
</button>� </div>
</tab-pane>�...
AngularJS 2.0
<div>� <input type="text" [value]="newTodoTitle">� <button (click)="addTodo()">+</buton>�� <tab-container>� <tab-pane title="Good kids">� <div [ng-repeat|todo]="todosOf('good')">� <input type="checkbox"
[checked]="todo.done">� {{todo.title}}� <button (click)="deleteTodo(todo)">
X
</button>� </div>
</tab-pane>�...
[value]="newTodoTitle"
(click)="addTodo()"
[ng-repeat|todo]="todosOf('good')"
[checked]="todo.done"
{{todo.title}}
(click)="deleteTodo(todo)"
AngularJS 2.0
<div>� <input type="text" [value]="newTodoTitle">� <button (click)="addTodo()">+</buton>�� <tab-container>� <tab-pane title="Good kids">� <div [ng-repeat|todo]="todosOf('good')">� <input type="checkbox"
[checked]="todo.done">� {{todo.title}}� <button (click)="deleteTodo(todo)">
X
</button>� </div>
</tab-pane>�...
AngularJS 2.0
<div>� <input type="text" [value]="newTodoTitle">� <button (click)="addTodo()">+</buton>�� <tab-container>� <tab-pane title="Good kids">� <div [ng-repeat|todo]="todosOf('good')">� <input type="checkbox"
[checked]="todo.done">� {{todo.title}}� <button (click)="deleteTodo(todo)">
X
</button>� </div>
</tab-pane>�...
[checked]="todo.done"
Databinding
<elm attr="...">
elm.property=...
controllers
2009-2014
Directive Definition Object ("DDO")
myModule.directive('directiveName', function factory(injectables) {� return {� priority: 0,� template: '<div></div>', // or // function(tElement, tAttrs) { ... },� // or� // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },� transclude: false,� restrict: 'A',� templateNamespace: 'html',� scope: false,� controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },� controllerAs: 'stringAlias',� require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],� compile: function compile(tElement, tAttrs, transclude) {� return {� pre: function preLink(scope, iElement, iAttrs, controller) { ... },� post: function postLink(scope, iElement, iAttrs, controller) { ... }� }� // or� // return function postLink( ... ) { ... }� },� // or� // link: {� // pre: function preLink(scope, iElement, iAttrs, controller) { ... },� // post: function postLink(scope, iElement, iAttrs, controller) { ... }� // }� // or� // link: function postLink( ... ) { ... }� };�});
DDO
2009-2014
SantaTodoApp component
@ComponentDirective
class SantaTodoApp {
constructor() {
this.newTodoTitle = '';
}
addTodo: function() { ... }
removeTodo: function(todo) { ... }
todosOf: function(filter) { ... }
}
SantaTodoApp component
@ComponentDirective({ ... })
class SantaTodoApp { ... }
@TemplateDirective({ ... })
class NgRepeat { ... }
@DecoratorDirective({ ... })
class NgClass { ... }
SantaTodoApp component
@ComponentDirective
class SantaTodoApp {
constructor() {
this.newTodoTitle = '';
}
addTodo: function() { ... }
removeTodo: function(todo) { ... }
todosOf: function(filter) { ... }
}
$scope
2009-2014
ng-repeat and $parent
Selected user: {{selectedUser.name}}
<div ng-repeat="user in users"
ng-click="selectedUser = user">
</div>
ng-repeat and $parent
Selected user: {{selectedUser.name}}
<div ng-repeat="user in users"
ng-click="$parent.selectedUser = user">
</div>
Registering directives
@ComponentDirective({
directives: [TabContainer, TabPane, NgRepeat]
})
class SantaTodoApp {
constructor() {
this.newTodoTitle = '';
}
addTodo: function() { ... }
removeTodo: function(todo) { ... }
todosOf: function(filter) { ... }
}
Dependency Injection
Defining services
class TodoStore {
constructor(win:Window) {
this.win = win;
}
add(todo) {
// access this.win.localStorage ...
}
remove(todo) { ... }
todosOf(filter) { ... }
}
angular�.module
2009-2014
Using services
import {TodoStore} from './store';
@ComponentDirective({
directives: [TabContainer, TabPane, NgRepeat]
})
class SantaTodoApp {
constructor(store:TodoStore) {
...
}
...
}
Directives and DI
<tab-container>
<tab-pane title="Tobias">
New Macbook Pro
Tesla Model X
...
</tab-pane>
<tab-pane title="Good kids">
...
</tab-pane>
<tab-pane title="Bad kids">
...
</tab-pane>
</tab-container>
Directives and DI
class TabContainer {
constructor(tabs:Query<TabPane>) { ... }
...
}
class TabPane {
constructor(
tabContainer:TabContainer,
element:HTMLElement
) { ... }
...
}
Performance
Measure
Analyze
Improve
Measure
Macro optimizations
jqLite
2009-2014
<div>� <input type="text" [value]="newTodoTitle">� <button (click)="addTodo()">+</buton>�� <tab-container>� <tab-pane title="Good kids">� <div [ng-repeat|todo]="todosOf('good')">� <input type="checkbox"
[checked]="todo.don� {{todo.title}}� <button (click)="deleteTo
X
</button>� </div>
</tab-pane>�...
Analyze
Analyze - Web Tracing Framework
Summary
controllers
DDO
$scope
angular.module
jqLite
generic binding syntax
benchpress
WTF instrumentation
DI query mechanism
ng-europe 2014