SlideShare a Scribd company logo
Zukunftssichere Anwendungen
mit AngularJS 1.x entwickeln
Christian Janz (@c_janz)
christian.janz@bridging-it.de
Wer steht hier vorne?
Christian Janz
Consultant bei BridgingIT GmbH in Mannheim
Interesse: Architektur und Entwicklung von
Geschäftsanwendungen mit modernen Frameworks
AngularJS 1.x? Warum nicht Angular 2?
“Angular 2 is currently in Developer Preview. We recommend using Angular 1.X
for production applications.”
https://angular.io/docs/ts/latest/
Dilemma?
1.x 2
Entwickle die Anwendung mit AngularJS 1.x,
aber mit Angular 2 im Blick
Lösungsansatz
Neuerung in Angular 2
Eine Auswahl :-)
Neue Template-Syntax
1. <li *ng-for="#hero of heroes" (click)="onSelect(hero)">
2. <span class="badge">{{hero.id}}</span> {{hero.name}}
3. </li>
ES 2015 Support / TypeScript
● Angular 2 wird in TypeScript entwickelt
● Verwendet ES 2015 Module
○ Framework wird modularer
○ Kein eigenes Modulsystem mehr (angular.
module(...))
● Einsatz von Decorators für Metadaten
1. import {bootstrap, Component} from
'angular2/angular2';
2.
3. @Component({
4. selector: 'my-app',
5. template: '<h1>My First Angular 2 App</h1>'
6. })
7. class AppComponent { }
8.
9. bootstrap(AppComponent);
Verbesserte Dependency Injection
● Hierarchische Dependency Injection Container
● Matching der Abhängigkeiten über Typ, nicht über Name
Komponentenbasiert
● Keine Standalone Controller mehr (ng-controller=””)
● Kein $scope mehr
● @Component: Komponente (≅ AngularJS 1.x Direktiven)
● @Directive: Komponente ohne View
Neuer Router
● Komponentenbasiert
● Deutlich mächtiger als ng-route
● Parallelentwicklung für Angular 2 und Angular 1.x
○ Gleiche API
○ Soll Migration erleichtern
TypeScript
TypeScript und EcmaScript
ES 5
ES 2015
TypeScript
ES 2015 Module
Import, Export
http://www.2ality.com/2014/09/es6-modules-final.html
// lib/math.js
export function sum(x, y) {
return x + y;
}
export const pi = 3.141593;
// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
Default Export
http://www.2ality.com/2014/09/es6-modules-final.html
//------ myFunc.js ------
export default function foo() { ... };
//------ main1.js ------
import myFunc from 'myFunc';
// import { default as foo } from 'myFunc';
myFunc();
Module Loader API
http://www.2ality.com/2014/09/es6-modules-final.html
System.import('lib/debug').then(function(m) {
// do something with the module m
});
Browser-Support
Kein Browser unterstützt bisher nativ ES 2015 Module
⇒ Bibliotheken/Tools notwendig
Refactoring Patterns
Services & Bootstrapping
Services
angular.module('myTestApp')
.factory('gitHubService', function ($http) {
function buildRepoUrl(userId) {
return
'https://api.github.com/users/'
+ userId + '/repos';
}
function getRepos(userId) {
return $http.get(buildRepoUrl(userId))
.then(function (result) {
return result.data;
});
}
return {
getRepos: getRepos
}
});
export default class GitHubService {
constructor(private $http: angular.IHttpService) {
}
private buildRepoUrl(userId: string): string {
return `https://api.github.com/users/${userId}
/repos`;
}
public getRepos(userId: string): any {
return this.$http.get(this.buildRepoUrl(userId))
.then(function (result) {
return result.data;
});
}
}
Bootstrapping
//app.js
angular.module('myTestApp', []);
------------
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Old Code</title>
</head>
<body ng-app="myTestApp">
<script src="bower_components/angular/angular.js"
></script>
<script src="app.js"></script>
<script src="github.service.js"></script>
</body>
</html>
//app.ts
import angular = require('angular');
import GitHubService from './github.service';
let module = angular.module('myTestApp', [])
.service('gitHubService', GitHubService);
angular.bootstrap(window.document.body, [module.name]);
------------
//index.html
<!DOCTYPE html>
<html lang="en">
<head>...</head>
<body>
<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>
<script>
System.import('lib/app');
</script>
</body>
</html>
Refactoring Patterns
Controller & Direktiven
ng-controller durch Komponente ersetzen Teil 1: Controller Aliasing
//index.html
<body ng-app="myTestApp">
<main ng-controller="MainCtrl">
<ul ng-controller="RepoListCtrl">
<li ng-repeat="repo in repos"
ng-click="selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{selectedRepo}}
</div>
</main>
</body>
//index.html
<body ng-app="myTestApp">
<main ng-controller="MainCtrl as mainCtrl">
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
</body>
//index.html
<body ng-app="myTestApp">
<main ng-controller="MainCtrl as mainCtrl">
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
</body>
ng-controller durch Komponente ersetzen Teil 2: Direktive erstellen
//index.html
<body ng-app="myTestApp">
<main-app></main-app>
</body>
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
return {
scope: true,
templateUrl: 'mainApp.template.html'
}
})
//mainApp.template.html
<main ng-controller="MainCtrl as mainCtrl">
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
ng-controller durch Komponente ersetzen Teil 3: Root ng-controller entfernen
//index.html
<body ng-app="myTestApp">
<main-app></main-app>
</body>
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
return {
scope: true,
templateUrl: 'mainApp.template.html'
}
})
//mainApp.template.html
<main ng-controller="MainCtrl as mainCtrl">
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
//index.html
<body ng-app="myTestApp">
<main-app></main-app>
</body>
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
return {
scope: true,
controller: 'MainCtrl',
controllerAs: 'mainCtrl',
templateUrl: 'mainApp.template.html'
}
})
//mainApp.template.html
<main>
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
ng-controller durch Komponente ersetzen Teil 4: Direktive und Controller kombinieren
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
return {
scope: true,
controller: 'MainCtrl',
controllerAs: 'mainCtrl',
templateUrl: 'mainApp.template.html'
}
})
//main.ctrl.js
angular.module('myTestApp')
.controller('MainCtrl', function () {
this.userId = 'bridgingIT';
this.selectedRepo = '';
this.selectRepo = function(repo) {
this.selectedRepo = repo;
}
});
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
function MainCtrl() {
this.userId = 'bridgingIT';
this.selectedRepo = '';
this.selectRepo = function(repo) {
this.selectedRepo = repo;
}
}
return {
scope: true,
controller: MainCtrl,
controllerAs: 'mainCtrl',
templateUrl: 'mainApp.template.html'
}
});
ng-controller durch Komponente ersetzen Teil 4b: Direktive in TypeScript
//main.directive.js
angular.module('myTestApp')
.directive('mainApp', function() {
function MainCtrl() {
this.userId = 'bridgingIT';
this.selectedRepo = '';
this.selectRepo = function(repo) {
this.selectedRepo = repo;
}
}
return {
scope: true,
controller: MainCtrl,
controllerAs: 'mainCtrl',
templateUrl: 'mainApp.template.html'
}
});
//main.directive.ts
class MainController {
public userId: string = 'bridgingIT';
public selectedRepo: string = '';
public onSelectRepo(repo: string) {
this.selectedRepo = repo;
}
}
export default () => {
return {
scope: {},
controller: MainController,
controllerAs: 'mainCtrl',
templateUrl: 'mainApp.template.html',
bindToController: true,
}
}
//app.ts
import angular = require('angular');
import MainComponent from './main.directive;
let module = angular.module('myTestApp', [])
.directive('mainApp', MainComponent)
angular.bootstrap(window.document.body, [module.name]);
ng-controller durch Komponente ersetzen Teil 5: Teilkomponente extrahieren
//mainApp.template.html
<main>
<ul ng-controller="RepoListCtrl as repoListCtrl">
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
//mainApp.template.html
<main>
<repo-list></repo-list>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
// repoList.directive.js
angular.module('myTestApp')
.directive('repoList', function () {
function RepoListCtrl($scope, gitHubService) {
var that = this;
$scope.$watch('mainCtrl.userId', function (newUserId) {
gitHubService.getRepos(newUserId)
.then(function (result) {
that.repos = result.map(function (repo) {
return repo.name;
});
});
});
}
return {
scope: true,
controller: RepoListCtrl,
controllerAs: 'repoListCtrl',
templateUrl: 'repoList.template.html'
}
});
ng-controller durch Komponente ersetzen Teil 5: Input und Output Parameter
// repoList.directive.js
angular.module('myTestApp')
.directive('repoList', function () {
function RepoListCtrl($scope, gitHubService) {
var that = this;
$scope.$watch('mainCtrl.userId', function (newUserId) {
gitHubService.getRepos(newUserId)
.then(function (result) {
that.repos = result.map(function (repo) {
return repo.name;
});
});
});
}
return {
scope: true,
controller: RepoListCtrl,
controllerAs: 'repoListCtrl',
templateUrl: 'repoList.template.html'
}
});
// repoList.template.html
<ul>
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="mainCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
//mainApp.template.html
<main>
<repo-list></repo-list>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
ng-controller durch Komponente ersetzen Teil 5: Input und Output Parameter
// repoList.directive.js
angular.module('myTestApp')
.directive('repoList', function () {
function RepoListCtrl($scope, gitHubService) {
var that = this;
$scope.$watch('repoListCtrl.userId', function (newUserId) {
gitHubService.getRepos(newUserId)
.then(function (result) {
that.repos = result.map(function (repo) {
return repo.name;
});
});
});
this.selectRepo = function(repo) {
that.onSelectRepo({repo: repo});
}
}
return {
scope: {
userId: '=',
onSelectRepo: '&'
},
bindToController: true,
controller: RepoListCtrl,
controllerAs: 'repoListCtrl',
templateUrl: 'repoList.template.html'
}
});
// repoList.template.html
<ul>
<li ng-repeat="repo in repoListCtrl.repos"
ng-click="repoListCtrl.selectRepo(repo)">
{{repo}}
</li>
</ul>
//mainApp.template.html
<main>
<repo-list
user-id="mainCtrl.userId"
on-select-repo="mainCtrl.selectRepo(repo)">
</repo-list>
<div>
Selected Repo: {{mainCtrl.selectedRepo}}
</div>
</main>
https://github.com/cjanz/angular-refactoring-patterns
Bitte noch mal langsam...
ngUpgrade
AngularJS 1.x und Angular 2 in einer Anwendung
https://github.com/angular/ngUpgrade
Fazit
AngularJS 1.x ist nicht tot
● Einige Ansätze aus Angular 2 können auch in
AngularJS 1.x genutzt werden
○ ES 2015 Module
○ Komponenten
● TypeScript erleichtert Refactoring
● Parallelbetrieb und schrittweise Migration sind
möglich
Fragen?
Danke für die Aufmerksamkeit :-)

More Related Content

PPTX
Angular 2 어디까지 왔을까
PDF
A gently introduction to AngularJS
PDF
A Story about AngularJS modularization development
PDF
Building a Startup Stack with AngularJS
PDF
AngularJS application architecture
PDF
125 고성능 web view-deview 2013 발표 자료_공유용
PDF
AngularJS - Overcoming performance issues. Limits.
PDF
AngularJS Best Practices
Angular 2 어디까지 왔을까
A gently introduction to AngularJS
A Story about AngularJS modularization development
Building a Startup Stack with AngularJS
AngularJS application architecture
125 고성능 web view-deview 2013 발표 자료_공유용
AngularJS - Overcoming performance issues. Limits.
AngularJS Best Practices

What's hot (19)

PPTX
How to Build SPA with Vue Router 2.0
PPTX
Vue business first
ODP
AngularJs Crash Course
PDF
Introduction to VueJS & Vuex
PDF
Heroku pop-behind-the-sense
PDF
Building scalable applications with angular js
PPTX
AngularJS - The Next Big Thing?
PDF
Multi modularized project setup with gulp, typescript and angular.js
PPTX
Vue 2.0 + Vuex Router & Vuex at Vue.js
PDF
Vue js 大型專案架構
PDF
Angular JS blog tutorial
PDF
Introduction to AngularJS
PDF
Angularjs - lazy loading techniques
PDF
Vue routing tutorial getting started with vue router
PDF
AngularJS Basics and Best Practices - CC FE &UX
PDF
Vue.js is boring - and that's a good thing
PDF
Vue.js
PPTX
Backbone.js
How to Build SPA with Vue Router 2.0
Vue business first
AngularJs Crash Course
Introduction to VueJS & Vuex
Heroku pop-behind-the-sense
Building scalable applications with angular js
AngularJS - The Next Big Thing?
Multi modularized project setup with gulp, typescript and angular.js
Vue 2.0 + Vuex Router & Vuex at Vue.js
Vue js 大型專案架構
Angular JS blog tutorial
Introduction to AngularJS
Angularjs - lazy loading techniques
Vue routing tutorial getting started with vue router
AngularJS Basics and Best Practices - CC FE &UX
Vue.js is boring - and that's a good thing
Vue.js
Backbone.js
Ad

Viewers also liked (20)

PDF
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
PDF
Keeping Things Simple In A Growing AngularJS App.
PPTX
AngularJS Best Practices
PPTX
AngularJS $http Interceptors (Explanation and Examples)
PDF
AngularJS performance & production tips
PDF
Singapore startup ecosystem and entrepreneur toolbox - Jun 2014
PPTX
AngularJS Architecture
PPTX
Medienbiographie
PPT
1 .produktpräsenter 25 folien mit dvd
PPT
Ciclos Grado Medio
PDF
KTM Technologies: Konzeptvergleich eines Fahrzeugheckrahmens hinsichtlich Fes...
PPS
El pelotazo viaja en ave.
PPS
Me Asusta
PPS
FAMOSAS SIN MAQUILLAJE
PPTX
EPIDEMIOLOGIA
PPT
Hubble - Parte 4
PPTX
Trabajo final heli
PPS
Educación Sexual
PPTX
Basar
PPT
Por El Papa
Building Enterprise Applications with AngularJS (GDG DevFest Karlsruhe 2014)
Keeping Things Simple In A Growing AngularJS App.
AngularJS Best Practices
AngularJS $http Interceptors (Explanation and Examples)
AngularJS performance & production tips
Singapore startup ecosystem and entrepreneur toolbox - Jun 2014
AngularJS Architecture
Medienbiographie
1 .produktpräsenter 25 folien mit dvd
Ciclos Grado Medio
KTM Technologies: Konzeptvergleich eines Fahrzeugheckrahmens hinsichtlich Fes...
El pelotazo viaja en ave.
Me Asusta
FAMOSAS SIN MAQUILLAJE
EPIDEMIOLOGIA
Hubble - Parte 4
Trabajo final heli
Educación Sexual
Basar
Por El Papa
Ad

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Machine learning based COVID-19 study performance prediction
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
Cloud computing and distributed systems.
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Encapsulation theory and applications.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Electronic commerce courselecture one. Pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
Spectral efficient network and resource selection model in 5G networks
Network Security Unit 5.pdf for BCA BBA.
Chapter 3 Spatial Domain Image Processing.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Machine learning based COVID-19 study performance prediction
“AI and Expert System Decision Support & Business Intelligence Systems”
Advanced methodologies resolving dimensionality complications for autism neur...
Dropbox Q2 2025 Financial Results & Investor Presentation
Understanding_Digital_Forensics_Presentation.pptx
MYSQL Presentation for SQL database connectivity
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Cloud computing and distributed systems.
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Encapsulation theory and applications.pdf
A Presentation on Artificial Intelligence
Electronic commerce courselecture one. Pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Agricultural_Statistics_at_a_Glance_2022_0.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf

Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln (GDG DevFest Karlsruhe 2015)

  • 1. Zukunftssichere Anwendungen mit AngularJS 1.x entwickeln Christian Janz (@c_janz) christian.janz@bridging-it.de
  • 2. Wer steht hier vorne? Christian Janz Consultant bei BridgingIT GmbH in Mannheim Interesse: Architektur und Entwicklung von Geschäftsanwendungen mit modernen Frameworks
  • 3. AngularJS 1.x? Warum nicht Angular 2? “Angular 2 is currently in Developer Preview. We recommend using Angular 1.X for production applications.” https://angular.io/docs/ts/latest/
  • 5. Entwickle die Anwendung mit AngularJS 1.x, aber mit Angular 2 im Blick Lösungsansatz
  • 6. Neuerung in Angular 2 Eine Auswahl :-)
  • 7. Neue Template-Syntax 1. <li *ng-for="#hero of heroes" (click)="onSelect(hero)"> 2. <span class="badge">{{hero.id}}</span> {{hero.name}} 3. </li>
  • 8. ES 2015 Support / TypeScript ● Angular 2 wird in TypeScript entwickelt ● Verwendet ES 2015 Module ○ Framework wird modularer ○ Kein eigenes Modulsystem mehr (angular. module(...)) ● Einsatz von Decorators für Metadaten 1. import {bootstrap, Component} from 'angular2/angular2'; 2. 3. @Component({ 4. selector: 'my-app', 5. template: '<h1>My First Angular 2 App</h1>' 6. }) 7. class AppComponent { } 8. 9. bootstrap(AppComponent);
  • 9. Verbesserte Dependency Injection ● Hierarchische Dependency Injection Container ● Matching der Abhängigkeiten über Typ, nicht über Name
  • 10. Komponentenbasiert ● Keine Standalone Controller mehr (ng-controller=””) ● Kein $scope mehr ● @Component: Komponente (≅ AngularJS 1.x Direktiven) ● @Directive: Komponente ohne View
  • 11. Neuer Router ● Komponentenbasiert ● Deutlich mächtiger als ng-route ● Parallelentwicklung für Angular 2 und Angular 1.x ○ Gleiche API ○ Soll Migration erleichtern
  • 13. TypeScript und EcmaScript ES 5 ES 2015 TypeScript
  • 15. Import, Export http://www.2ality.com/2014/09/es6-modules-final.html // lib/math.js export function sum(x, y) { return x + y; } export const pi = 3.141593; // app.js import * as math from "lib/math"; alert("2π = " + math.sum(math.pi, math.pi)); // otherApp.js import {sum, pi} from "lib/math"; alert("2π = " + sum(pi, pi));
  • 16. Default Export http://www.2ality.com/2014/09/es6-modules-final.html //------ myFunc.js ------ export default function foo() { ... }; //------ main1.js ------ import myFunc from 'myFunc'; // import { default as foo } from 'myFunc'; myFunc();
  • 18. Browser-Support Kein Browser unterstützt bisher nativ ES 2015 Module ⇒ Bibliotheken/Tools notwendig
  • 20. Services angular.module('myTestApp') .factory('gitHubService', function ($http) { function buildRepoUrl(userId) { return 'https://api.github.com/users/' + userId + '/repos'; } function getRepos(userId) { return $http.get(buildRepoUrl(userId)) .then(function (result) { return result.data; }); } return { getRepos: getRepos } }); export default class GitHubService { constructor(private $http: angular.IHttpService) { } private buildRepoUrl(userId: string): string { return `https://api.github.com/users/${userId} /repos`; } public getRepos(userId: string): any { return this.$http.get(this.buildRepoUrl(userId)) .then(function (result) { return result.data; }); } }
  • 21. Bootstrapping //app.js angular.module('myTestApp', []); ------------ //index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Old Code</title> </head> <body ng-app="myTestApp"> <script src="bower_components/angular/angular.js" ></script> <script src="app.js"></script> <script src="github.service.js"></script> </body> </html> //app.ts import angular = require('angular'); import GitHubService from './github.service'; let module = angular.module('myTestApp', []) .service('gitHubService', GitHubService); angular.bootstrap(window.document.body, [module.name]); ------------ //index.html <!DOCTYPE html> <html lang="en"> <head>...</head> <body> <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import('lib/app'); </script> </body> </html>
  • 23. ng-controller durch Komponente ersetzen Teil 1: Controller Aliasing //index.html <body ng-app="myTestApp"> <main ng-controller="MainCtrl"> <ul ng-controller="RepoListCtrl"> <li ng-repeat="repo in repos" ng-click="selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{selectedRepo}} </div> </main> </body> //index.html <body ng-app="myTestApp"> <main ng-controller="MainCtrl as mainCtrl"> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main> </body>
  • 24. //index.html <body ng-app="myTestApp"> <main ng-controller="MainCtrl as mainCtrl"> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main> </body> ng-controller durch Komponente ersetzen Teil 2: Direktive erstellen //index.html <body ng-app="myTestApp"> <main-app></main-app> </body> //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { return { scope: true, templateUrl: 'mainApp.template.html' } }) //mainApp.template.html <main ng-controller="MainCtrl as mainCtrl"> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main>
  • 25. ng-controller durch Komponente ersetzen Teil 3: Root ng-controller entfernen //index.html <body ng-app="myTestApp"> <main-app></main-app> </body> //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { return { scope: true, templateUrl: 'mainApp.template.html' } }) //mainApp.template.html <main ng-controller="MainCtrl as mainCtrl"> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main> //index.html <body ng-app="myTestApp"> <main-app></main-app> </body> //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { return { scope: true, controller: 'MainCtrl', controllerAs: 'mainCtrl', templateUrl: 'mainApp.template.html' } }) //mainApp.template.html <main> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main>
  • 26. ng-controller durch Komponente ersetzen Teil 4: Direktive und Controller kombinieren //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { return { scope: true, controller: 'MainCtrl', controllerAs: 'mainCtrl', templateUrl: 'mainApp.template.html' } }) //main.ctrl.js angular.module('myTestApp') .controller('MainCtrl', function () { this.userId = 'bridgingIT'; this.selectedRepo = ''; this.selectRepo = function(repo) { this.selectedRepo = repo; } }); //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { function MainCtrl() { this.userId = 'bridgingIT'; this.selectedRepo = ''; this.selectRepo = function(repo) { this.selectedRepo = repo; } } return { scope: true, controller: MainCtrl, controllerAs: 'mainCtrl', templateUrl: 'mainApp.template.html' } });
  • 27. ng-controller durch Komponente ersetzen Teil 4b: Direktive in TypeScript //main.directive.js angular.module('myTestApp') .directive('mainApp', function() { function MainCtrl() { this.userId = 'bridgingIT'; this.selectedRepo = ''; this.selectRepo = function(repo) { this.selectedRepo = repo; } } return { scope: true, controller: MainCtrl, controllerAs: 'mainCtrl', templateUrl: 'mainApp.template.html' } }); //main.directive.ts class MainController { public userId: string = 'bridgingIT'; public selectedRepo: string = ''; public onSelectRepo(repo: string) { this.selectedRepo = repo; } } export default () => { return { scope: {}, controller: MainController, controllerAs: 'mainCtrl', templateUrl: 'mainApp.template.html', bindToController: true, } } //app.ts import angular = require('angular'); import MainComponent from './main.directive; let module = angular.module('myTestApp', []) .directive('mainApp', MainComponent) angular.bootstrap(window.document.body, [module.name]);
  • 28. ng-controller durch Komponente ersetzen Teil 5: Teilkomponente extrahieren //mainApp.template.html <main> <ul ng-controller="RepoListCtrl as repoListCtrl"> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main> //mainApp.template.html <main> <repo-list></repo-list> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main> // repoList.directive.js angular.module('myTestApp') .directive('repoList', function () { function RepoListCtrl($scope, gitHubService) { var that = this; $scope.$watch('mainCtrl.userId', function (newUserId) { gitHubService.getRepos(newUserId) .then(function (result) { that.repos = result.map(function (repo) { return repo.name; }); }); }); } return { scope: true, controller: RepoListCtrl, controllerAs: 'repoListCtrl', templateUrl: 'repoList.template.html' } });
  • 29. ng-controller durch Komponente ersetzen Teil 5: Input und Output Parameter // repoList.directive.js angular.module('myTestApp') .directive('repoList', function () { function RepoListCtrl($scope, gitHubService) { var that = this; $scope.$watch('mainCtrl.userId', function (newUserId) { gitHubService.getRepos(newUserId) .then(function (result) { that.repos = result.map(function (repo) { return repo.name; }); }); }); } return { scope: true, controller: RepoListCtrl, controllerAs: 'repoListCtrl', templateUrl: 'repoList.template.html' } }); // repoList.template.html <ul> <li ng-repeat="repo in repoListCtrl.repos" ng-click="mainCtrl.selectRepo(repo)"> {{repo}} </li> </ul> //mainApp.template.html <main> <repo-list></repo-list> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main>
  • 30. ng-controller durch Komponente ersetzen Teil 5: Input und Output Parameter // repoList.directive.js angular.module('myTestApp') .directive('repoList', function () { function RepoListCtrl($scope, gitHubService) { var that = this; $scope.$watch('repoListCtrl.userId', function (newUserId) { gitHubService.getRepos(newUserId) .then(function (result) { that.repos = result.map(function (repo) { return repo.name; }); }); }); this.selectRepo = function(repo) { that.onSelectRepo({repo: repo}); } } return { scope: { userId: '=', onSelectRepo: '&' }, bindToController: true, controller: RepoListCtrl, controllerAs: 'repoListCtrl', templateUrl: 'repoList.template.html' } }); // repoList.template.html <ul> <li ng-repeat="repo in repoListCtrl.repos" ng-click="repoListCtrl.selectRepo(repo)"> {{repo}} </li> </ul> //mainApp.template.html <main> <repo-list user-id="mainCtrl.userId" on-select-repo="mainCtrl.selectRepo(repo)"> </repo-list> <div> Selected Repo: {{mainCtrl.selectedRepo}} </div> </main>
  • 33. AngularJS 1.x und Angular 2 in einer Anwendung https://github.com/angular/ngUpgrade
  • 34. Fazit
  • 35. AngularJS 1.x ist nicht tot ● Einige Ansätze aus Angular 2 können auch in AngularJS 1.x genutzt werden ○ ES 2015 Module ○ Komponenten ● TypeScript erleichtert Refactoring ● Parallelbetrieb und schrittweise Migration sind möglich
  • 37. Danke für die Aufmerksamkeit :-)