Angular 2
IN ACTION
NG2 INTRODUCTION
Part 2
TSD
TSD
npm install tsd -g
tsd install angular2/angular2 angular2/router rx es6-promise
TSC
tsc app.ts --target ES5
--module system --experimentalDecorators
--moduleResolution node
--emitDecoratorMetadata
--outFile app.js
Start
HTML
<!doctype html>
<html lang="en">
<body>
<my-app></my-app>
<script src="js/bundle.js"></script>
</body>
</html>
APP.TS - IMPORTS
/// <reference path="../../typings/tsd.d.ts" />
import {
Component,
View,
bootstrap,
CORE_DIRECTIVES,
FORM_DIRECTIVES,
provide
} from 'angular2/angular2';
//...
APP.TS - COMPONENT
@Component({
selector: 'my-app',
template: APP_TEMPLATE,
directives: [HeaderComponent,
ROUTER_DIRECTIVES],
provides: [PostsStorage, Core]
})
class AppComponent {}
APP.TS - BOOTSTRAP
bootstrap(AppComponent, [
// Common
PostsStorage,
Core,
// Ng2
ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(APP_BASE_HREF, {useValue: '/'})
]);
Templates
TEMPLATES - IMPORT
import {
APP_TEMPLATE
} from './templates';
TEMPLATES - EXAMPLE COMPONENT
class AppComponent {
text:string = 'hello';
typing($event){
this.text = $event.target.value;
}
}
TEMPLATES - CODE
<h1>Bound Textbox</h1>
<input
[value]="text"
(keyup)="typing($event)" />
{{text}}
TEMPLATES - SYNTAX
<todo-cmp [model]="my_value"></todo-cmp>
<input
[ng-model]="todo.text"
(ng-model-change)="todo.text=$event"
></input>
<input [(ng-model)]="todo.text"></input>
TEMPLATES - SYNTAX
<video-player #player></video-player>
<button (click)="player.pause()">
Pause
</button>
<input #i>
{{i.value}}
PIPE
PIPE - USAGE
@Pipe({
name: 'publicName'
})
class ClassPipeName implements PipeTransform {
transform(value: number, args: any[]) {
//…
}
}
PIPE - USAGE
@Pipe({
name: 'publicName'
})
class ClassPipeName implements PipeTransform {
transform(value: number, args: any[]) {
//…
}
}
Routing
ROUTING - @RouteConfig
import {
AboutComponent
} from './components/about/index';
@RouteConfig([{
path: '/About/:id',
component: AboutComponent,
name: 'About'
}])
class AppComponent {}
ROUTING - @RouteConfig
export class AboutComponent {
id: number;
constructor( @Inject(RouteParams) params: RouteParams) {
this.id = params.get('id');
}
}
ROUTING - TEMPLATE
<nav>
<ul>
<a [router-link]="['./About', {id: 1}]" href="#"
class="list-group-item">About</a>
<a [router-link]="['./Home']" href="#" class="list-group-
item">Home</a>
<a [router-link]="['./PostsList']" href="#" class="list-
group-item">Posts list</a>
</ul>
</nav>
<route-transclusion name="main"></route-transclusion>
LINKS
react / angular / angular2
ng-conf
● https://github.com/htdt/ng2-jspm
● https://github.com/thelgevold/angular-2-samples
● http://www.syntaxsuccess.com/angular-2-articles
●
BUILDING / COMPILE /
TRANSCRIPTION
Part 2
Browserify
ROUTING - TEMPLATE
var browserify = require('gulp-browserify');
gulp.src('build/ts/app/app.js')
.pipe(browserify({
insertGlobals : true,
debug : !gulp.env.production
}))
.pipe(gulp.dest('./dist/app'))
NO
JSPM
JSMP
“jspm is a package manager for the SystemJS universal module
loader, built on top of the dynamic ES6 module loader”
React applications with JSPM
JSMP
● ES6, AMD, CommonJS and globals)
● npm and GitHub...
● load modules as separate files
● optimize into a bundle
● realtime transcript
System.js
SYSTEM.JS - PRODUCTION
npm install -g jspm
jspm init
jspm install angular2/angular2
jspm bundle-sfx --minify zone.js + whatwg-fetch + reflect-metadata
+ src/app/app dist/js/bundle.js
SYSTEM.JS - DEVELOPMENT
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
System.import('reflect-metadata')
.then(function(){System.import('zone.js')})
// .then(function(){System.import('es5-shim')}) <- LOL
.then(function(){System.import('es6-shim')})
.then(function(){System.import('whatwg-fetch')})
.then(function(){System.import('src/app/app')});
</script>
SYSTEM.JS - PRODUCTION
<!doctype html>
<html lang="en">
<body>
<my-app></my-app>
<script src="js/bundle.js"></script>
</body>
</html>
Gulp
GULP - TEMPLATES
var ng2Template = "export const <%= template.url %> = '<%=
template.escapedContent %>';n";
function fnRename(templateUrl, templateFile) {
var pathParts = templateUrl.replace('.tpl.html', '').split('/'),
folder = pathParts[pathParts.length - 2],
file = pathParts[pathParts.length - 1],
name = (folder ? folder + '_' : '') + file + '_TEMPLATE';
return name.toUpperCase().replace(/-[.-]/g,
function (match) {
return '_';
});
}
}
/*...*/.pipe(ngHtml2Js({
rename: fnRename,
template: ng2Template
})
PRERENDER
Part 3
Metadata
Metadata - HTML
<!doctype html>
<html lang="en">
<head>
<title>{{ no.work.here }}</title>
<head>
<body>
<my-app></my-app>
<script src="js/bundle.js"></script>
</body>
</html>
METADATA - SERVICE
export class HeadDOM {
private titleDom:HTMLElement;
get title():string {
return this.titleDom.innerText;
}
set title(title:string) {
this.titleDom.innerText = title;
this.ogTitle = title;
}
//…
}
Prerender.io
PRERENDER.IO - COST
PRERENDER.IO - GITHUB
https://github.com/prerender/prerender
Webrender-service
Webrender-service - Overview
● (+) Render png file
● (+) Render pdf file
● (+) Render html file
● (+) No-overwrite js functions
● (+) Servers whitelist
● (+) Token security
● (-) Legacy code
● (-) Small community
● (-) No-good tested
● (-) Use node-babel
● (-) Alpha
Webrender-service - Todo
● Remove babel (problems with debugging)
● Write unit tests
● Remove cache (I recommend to use solution like varnish)
WEBRENDER SERVICE (ALPHA) - GITHUB
https://bitbucket.org/spozoga/webrender-service
PhantomJS
PhantomJS - Error #1
Map is a pretty new structure. Use npm install harmony-collections --
save-dev and add "node_modules/harmony-collections/harmony-
collections.min.js", to the karma config.
PhantomJS - Error #2
ORIGINAL EXCEPTION: TypeError: 'undefined' is not a function
(evaluating 'window.requestAnimationFrame(callback)')
PhantomJS - Error #3
RangeError: Maximum call stack size exceeded.
at quote
(/Users/spozoga/dev/prerender/node_modules/phantom/shim.js:
1065)
………..
DevOps
VARNISH
PRERENDER.IO - GITHUB
https://github.com/prerender/prerender
PRERENDER-VARNISH - GITHUB
https://github.com/MWers/prerender-varnish
The end
Sebastian Pożoga
sebastian@pozoga.eu

Angular2 - In Action