SlideShare una empresa de Scribd logo
1 de 56
Descargar para leer sin conexión
HOW ANGULAR
CAN SOLVE
ALL YOUR PROBLEMS
Nir Kaufman
IT CAN’T
Nir Kaufman
- I don’t really need glasses to see
- This photo is a photoshop
- In reality I’m in color (and fatter)
Head of AngularJS Development @ 500Tech
INTRODUCTION
“We are not happy with our app.
it should be modular,
easy to extend and maintain.
It’s hard to understand the flow,
feels like a spaghetti
of presentation and business logic.
- frontend team at {{ company.name }}
WE NEED A BETTER
FRAMEWORK
WHAT DO WE NEED?
COMPONENTS
A clean way of organizing
your UI code into self-contained,
reusable chunks
// component controller

class likeBoxController {



constructor(params) {

this.chosenValue = params.value;

}



like() {

this.chosenValue('like');

}



dislike() {

this.chosenValue('dislike');

}

}



// component definition

function likeBoxComponent() {

return {

viewModel: likeBoxController,

template: likeBoxTemplate

}

}



// component registration

ko.components.register('like-widget', likeBoxComponent());
// component controller

class likeBoxController {



constructor() {

this.chosenValue = null;

}



like() {

this.chosenValue = 'like';

}



dislike() {

this.chosenValue = 'dislike';

}

}



// component definition

function likeBoxComponent() {

return {

controller: likeBoxController,

scope: { params: ‘=chosenValue' },

controllerAs: 'LikeBox',

bindToController: true,

template: likeBoxTemplate

}

}



angular.module('app', [])

.directive('likeWidget', likeBoxComponent);
<div class="like-or-dislike" data-bind="visible: !chosenValue()">

<button data-bind="click: like">Like it</button>

<button data-bind="click: dislike">Dislike it</button>

</div>



<div class="result" data-bind="visible: chosenValue">

You <strong data-bind="text: chosenValue"></strong> it

</div>
<div class="like-or-dislike" ng-hide="LikeBox.chosenValue">

<button ng-click="LikeBox.like()">Like it</button>

<button ng-click="LikeBox.dislike()">Dislike it</button>

</div>



<div class="result" ng-show="LikeBox.chosenValue">

You <strong ng-bind="LikeBox.chosenValue"></strong> it

</div>

class LikeWidget extends React.Component {



constructor(props) {

super(props);



this.state = { chosenValue: null };



this.like = this.like.bind(this);

this.dislike = this.dislike.bind(this);

this._likeButtons = this._likeButtons.bind(this)

}



like() {

this.setState({

chosenValue: 'like'

})

}



dislike() {

this.setState({

chosenValue: 'dislike'

})

}





_likeButtons() {

if (this.state.chosenValue) {

return null

}



return (

<div>

<button onClick={this.like}>Like it</button>

<button onClick={this.dislike}>Dislike it</button>

</div>

)

}



render() {

return (

<div>

{ this._likeButtons() }

{ this.state.chosenValue ?

<div>You <strong>{ this.state.chosenValue }</strong> it </div> : null}

</div>

)

}

}



React.render(<LikeWidget/>, document.getElementById('app'));
MVW PATTERN
Keep your business logic
separate from your user interface
class MyViewModel {



constructor() {

this.products = [

new Product('Garlic bread'),

new Product('Pain au chocolat'),

new Product('Seagull spaghetti', 'like')

];

}

}



ko.applyBindings(new MyViewModel());
class MyViewModel {



constructor() {

this.products = [

new Product('Garlic bread'),

new Product('Pain au chocolat'),

new Product('Seagull spaghetti', 'like')

];

}

}



angular.module('app', [])

.controller('MyViewModel', MyViewModel);
Backbone.Model.extend({

defaults: {

coverImage: 'img/placeholder.png',

title: 'No title',

author: 'Unknown',

releaseDate: 'Unknown',

keywords: 'None'

}

});
DS.Model.extend({

title: DS.attr('No title'),

author: DS.attr('Unknown'),

releaseDate: DS.attr('Unknown'),

keywords: DS.attr('None')

});
class Book {

constructor() {

this.coverImage = 'img/placeholder.png';

this.title = 'No title';

this.author = 'Unknown';

this.releaseDate = 'Unknown';

this.keywords = 'None';

}

}
LETS GET TO THE POINT
All major frameworks introduce
the same concepts.
Don’t make a switch for the
wrong reasons. Switching
to another framework won’t
solve your design problems.
OBJECT ORIENTED
PROGRAMMING
CONSIDER TYPESCRIPT
I used to hate it…
SOLID PRINCIPLES
Single Responsibility
Open / Closed
Liskov Substitution
Interface Segregation
Dependency Inversion
S.O.L.I.D
Single Responsibility Principle
A module should have one,
and only one reason to change
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(($stateProvider, $httpProvider, localStorageServiceProvider) => {



// start routing

$stateProvider

.state('dashboard', {

url: '/dashboard',

templateUrl: 'states/dashboard/dashboard.html',

controller: 'DashboardController'

})



.state('users', {

url: '/users',

templateUrl: 'states/users/users.html',

controller: 'UsersController'

});



// http configuration

$httpProvider.useApplyAsync(true);

$httpProvider.useLegacyPromiseExtensions(false);



$httpProvider.interceptors.push(($log) => {

return {

'request': function (config) {

$log.debug(config);

return config;

}

};

});



// storage configurations

localStorageServiceProvider

.setPrefix('myApp')

.setStorageType('sessionStorage')

});



// start engines

angular.bootstrap(document, ['app']);
4 reasons
to change
this module:
add dependency
add new state
configure http service
configure storage service
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(routes)

.config(http)

.config(storage)



// start engines

angular.bootstrap(document, ['app']);
export function routes($stateProvider) {

$stateProvider

.state('dashboard', {

url: '/dashboard',

templateUrl: 'states/dashboard/dashboard.html',

controller: 'DashboardController'

})



.state('users', {

url: '/users',

templateUrl: 'states/users/users.html',

controller: 'UsersController'

});

}

routes.ts
app.ts
export function http ($httpProvider) {

$httpProvider.useApplyAsync(true);

$httpProvider.useLegacyPromiseExtensions(false);

}
http.ts
export function storage(localStorageServiceProvider) {

localStorageServiceProvider

.setPrefix('myApp')

.setStorageType('sessionStorage')

}
storage.ts
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

.config(routes)

.config(http)

.config(storage)



// start engines

angular.bootstrap(document, ['app']);
Are we there yet?
2 reasons to change
// module declarations

angular.module('app', [

'ui.router',

'LocalStorageModule',

'app.states'

])

// start engines

angular.bootstrap(document, ['app']);
1 responsibility
S.O.L.I.D
Open / Closed Principle
A module should be open for
extension, but closed for
modification.
class Modal {



constructor($modal) {

this.modal = $modal;

}



show(type) {



switch (type) {

case 'login':

this.showLoginModal();

break;

case 'info':

this.showInfoModal();

break;

}

}



showLoginModal() {

this.modal.open({

template: 'loginModal.html',

controller: ‘loginModalController’

})

}



showInfoModal() {

this.modal.open({

template: 'infoModal.html',

controller: 'infoModalController'

})

}

}
class Controller {



constructor(Modal) {

this.Modal = Modal;

}



showLogin(){

this.Modal.show('login');

}

}
We need to add
new Modals to
our system
class Modal {



constructor($modal) {

this.modal = $modal;

this.modals = new Map();

}



register(type, config) {

this.modals.set(type, config)

}



$get() {

return { show: this.show }

}



show(type) {

if(this.modals.has(type)){

this.modal.open(this.modals.get(type))

}

}

}

angular.module('app', [])

.config(ModalProvider => {



ModalProvider.register('lostPassword', {

template: 'lostPassword.html',

controller: 'lostPasswordController'

})

});
class Controller {



constructor(Modal) {

this.Modal = Modal;

}



showLogin(){

this.Modal.show('lostPassword');

}

}
Write code that
can be extended
S.O.L.I.D
Liskov Substitution Principle
Child classes should never
break the parent class type definitions
IT’S ABOUT
INHERITANCE
DON’T DO IT
S.O.L.I.D
Interface Segregation Principle
Many specific interfaces
are better than one generic interface
I just want to make a copy
class LocalStorage {

private storage;

private $window;



constructor($window, $q) {

this.$window = $window;

}



setStorageType(type:string) {

if (type === 'local') {

return this.storage = this.$window.localStorage;

}

if (type === 'db') {

return this.storage = new PouchDB('DB');

}

}



setLocalItem(key:string, data) {

if (this.db) {

return this.db.put(JSON.parse(data))

}

return this.storage.setItem(key, JSON.stringify(data));

}
put(data) {

this.storage.put(JSON.parse(data))

}


getLocalItem(key:string):string {

let deferred = this.$q.defer();



if (this.db) {

this.db.get(key).then( result => deferred.resolve() )

}

deferred.resolve(this.storage.getItem());

return deferred.promise;

}

}
No client should be
forced to depend on
methods it doesn’t use
class LocalStorage {

private storage;



constructor($window) {

this.storage = $window.localStorage;

}





setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
class SessionStorage {

private storage;



constructor($window, $q) {

this.storage = $window.sessionStorage;

}



setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
localStorage.ts
sessionStorage.ts
class DBStorage {

private db;



constructor(PouchDB) {

this.db = new PouchDB('DB');

}



put(data) {

this.db.put(data)

}



get(id){

return this.db.get(id);

}

}
dbStorage.ts
UserComponent.ts (client)
class UserComponent {

private storage;



constructor(LocalStorage) {

this.storage = LocalStorage

}

}
S.O.L.I.D
Dependency Inversion Principle
High-level modules should not depend
on low-level modules. Both should
depend on abstractions.
NATIVE API’s
ANGULAR
3RD PARTY MODULES
APLLICATION CODE
INTERFACES
Application Layers
YOUR MODULES
Abstraction
Abstraction
interface IStorage {

setItem(key:string, data:any);

getItem(key:string, data:any);

}
IStorgae.ts UserComponent.ts (client)
class UserComponent {

private storage;



constructor(Storage: IStorage) {

this.storage = LocalStorage

}

}
LocalStorage.ts
class LocalStorage implements IStorage {

private storage;



constructor($window) {

this.storage = $window.localStorage;

}



setItem(key:string, data) {

return this.storage.setItem(key, JSON.stringify(data));

}



getItem(key:string):string {

return this.storage.getItem();

}

}
The ‘client’ can work
with any kind of storage
that implements the
IStorage interface
export class WelcomeController {



constructor($modal) {

this.$modal = $modal;

}



login() {

let loginModalInstance = this.$modal.open({

templateUrl: 'states/welcome/login_modal.html',

keyboard: false,

backdrop: 'static',

controller: LoginModalController,

controllerAs: 'Login'

});



loginModalInstance.result

.then(result => console.log(result))

}

}
Angular Bootstrap Modal
export class DashboardController {



constructor($modal) {

this.$modal = $modal;

}



showInfo() {

let infoModalInstance = this.$modal.open({

templateUrl: 'states/dashboard/info_modal.html',

keyboard: false,

backdrop: 'static',

controller: InfoModalController,

controllerAs: 'Info'

});



infoModalInstance.result

.then(result => console.log(result))

}

}
What is the problem?
class Modal {



constructor($modal) {

this.modal = $modal;

this.modals = new Map();

}



register(type, config) {

this.modals.set(type, config)

}



$get() {

return { show: this.show }

}



show(type) {

if(this.modals.has(type)){

this.modal.open(this.modals.get(type))

}

}

}

Abstraction without TypeScript
SUMMARY
DON’T MAKE A
SWITCH FOR
THE WRONG
REASONS
DESIGN PATTENS
MATTER
GOOD DESIGN
IS FRAMEWORK
AGNOSTIC
THANK YOU!
Angular ES6 / TypeScript Starters
https://github.com/nirkaufman/angular-webpack-starter
https://github.com/nirkaufman/angular-webpack-typescript-starter
resources
https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
http://code.tutsplus.com/series/the-solid-principles--cms-634
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Read our blog:
http://blog.500tech.com
Nir Kaufman
nir@500tech.com

Más contenido relacionado

La actualidad más candente

Keycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler WebinarKeycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler Webinarmarcuschristie
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web APIhabib_786
 
Token, token... From SAML to OIDC
Token, token... From SAML to OIDCToken, token... From SAML to OIDC
Token, token... From SAML to OIDCShiu-Fun Poon
 
OAuth2 - Introduction
OAuth2 - IntroductionOAuth2 - Introduction
OAuth2 - IntroductionKnoldus Inc.
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency InjectionNir Kaufman
 
Demystifying AuthN/AuthZ Using OIDC & OAuth2
Demystifying AuthN/AuthZ Using OIDC & OAuth2Demystifying AuthN/AuthZ Using OIDC & OAuth2
Demystifying AuthN/AuthZ Using OIDC & OAuth2NGINX, Inc.
 
Model view controller (mvc)
Model view controller (mvc)Model view controller (mvc)
Model view controller (mvc)M Ahsan Khan
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorialRohit Gupta
 
Modernize your Objective-C
Modernize your Objective-CModernize your Objective-C
Modernize your Objective-CMassimo Oliviero
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
FIWARE Wednesday Webinars - How to Design DataModels
FIWARE Wednesday Webinars - How to Design DataModelsFIWARE Wednesday Webinars - How to Design DataModels
FIWARE Wednesday Webinars - How to Design DataModelsFIWARE
 
Understanding JWT Exploitation
Understanding JWT ExploitationUnderstanding JWT Exploitation
Understanding JWT ExploitationAkshaeyBhosale
 
Nest.js Introduction
Nest.js IntroductionNest.js Introduction
Nest.js IntroductionTakuya Tejima
 
LASCON 2017: SAML v. OpenID v. Oauth
LASCON 2017: SAML v. OpenID v. OauthLASCON 2017: SAML v. OpenID v. Oauth
LASCON 2017: SAML v. OpenID v. OauthMike Schwartz
 
Introduction to SAML 2.0
Introduction to SAML 2.0Introduction to SAML 2.0
Introduction to SAML 2.0Mika Koivisto
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch APIXcat Liu
 

La actualidad más candente (20)

Keycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler WebinarKeycloak for Science Gateways - SGCI Technology Sampler Webinar
Keycloak for Science Gateways - SGCI Technology Sampler Webinar
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
 
Token, token... From SAML to OIDC
Token, token... From SAML to OIDCToken, token... From SAML to OIDC
Token, token... From SAML to OIDC
 
OAuth2 - Introduction
OAuth2 - IntroductionOAuth2 - Introduction
OAuth2 - Introduction
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
 
NestJS
NestJSNestJS
NestJS
 
Demystifying AuthN/AuthZ Using OIDC & OAuth2
Demystifying AuthN/AuthZ Using OIDC & OAuth2Demystifying AuthN/AuthZ Using OIDC & OAuth2
Demystifying AuthN/AuthZ Using OIDC & OAuth2
 
Model view controller (mvc)
Model view controller (mvc)Model view controller (mvc)
Model view controller (mvc)
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorial
 
Modernize your Objective-C
Modernize your Objective-CModernize your Objective-C
Modernize your Objective-C
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Single sign on using SAML
Single sign on using SAML Single sign on using SAML
Single sign on using SAML
 
FIWARE Wednesday Webinars - How to Design DataModels
FIWARE Wednesday Webinars - How to Design DataModelsFIWARE Wednesday Webinars - How to Design DataModels
FIWARE Wednesday Webinars - How to Design DataModels
 
Angular modules in depth
Angular modules in depthAngular modules in depth
Angular modules in depth
 
Understanding JWT Exploitation
Understanding JWT ExploitationUnderstanding JWT Exploitation
Understanding JWT Exploitation
 
Nest.js Introduction
Nest.js IntroductionNest.js Introduction
Nest.js Introduction
 
LASCON 2017: SAML v. OpenID v. Oauth
LASCON 2017: SAML v. OpenID v. OauthLASCON 2017: SAML v. OpenID v. Oauth
LASCON 2017: SAML v. OpenID v. Oauth
 
Introduction to SAML 2.0
Introduction to SAML 2.0Introduction to SAML 2.0
Introduction to SAML 2.0
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
 

Destacado

Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptmartinlippert
 
How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!Nir Kaufman
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015Nir Kaufman
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and runningNir Kaufman
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6Nir Kaufman
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes WorkshopNir Kaufman
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Nir Kaufman
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshopNir Kaufman
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Nir Kaufman
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS BasicsRavi Mone
 
AngularJS Introduction
AngularJS IntroductionAngularJS Introduction
AngularJS IntroductionCarlos Morales
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjsNir Kaufman
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - ServicesNir Kaufman
 
Solid JavaScript Coding
Solid JavaScript CodingSolid JavaScript Coding
Solid JavaScript CodingDiwa Del Mundo
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Nir Kaufman
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 
Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready Nir Kaufman
 

Destacado (20)

Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
 
How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!How Angular2 Can Improve Your AngularJS Apps Today!
How Angular2 Can Improve Your AngularJS Apps Today!
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and running
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes Workshop
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshop
 
Webstorm
WebstormWebstorm
Webstorm
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
 
AngularJS Introduction
AngularJS IntroductionAngularJS Introduction
AngularJS Introduction
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjs
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - Services
 
Solid JavaScript Coding
Solid JavaScript CodingSolid JavaScript Coding
Solid JavaScript Coding
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs
 
Angular redux
Angular reduxAngular redux
Angular redux
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready
 

Similar a Solid angular

JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularIlia Idakiev
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 formsEyal Vardi
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JSAlwyn Wymeersch
 
Angular.js is super cool
Angular.js is super coolAngular.js is super cool
Angular.js is super coolMaksym Hopei
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteRavi Bhadauria
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationDan Wahlin
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014Ran Wahle
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Python Ireland
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components EverywhereIlia Idakiev
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc trainingicubesystem
 
Embrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xLukas Ruebbelke
 

Similar a Solid angular (20)

AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
 
Angular 2.0 forms
Angular 2.0 formsAngular 2.0 forms
Angular 2.0 forms
 
CFUGbe talk about Angular JS
CFUGbe talk about Angular JSCFUGbe talk about Angular JS
CFUGbe talk about Angular JS
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Angular.js is super cool
Angular.js is super coolAngular.js is super cool
Angular.js is super cool
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Asp.net mvc training
Asp.net mvc trainingAsp.net mvc training
Asp.net mvc training
 
Embrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.x
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
MVC Training Part 2
MVC Training Part 2MVC Training Part 2
MVC Training Part 2
 

Más de Nir Kaufman

Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesNir Kaufman
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom buildersNir Kaufman
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developersNir Kaufman
 
Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Nir Kaufman
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanNir Kaufman
 
Boosting Angular runtime performance
Boosting Angular runtime performanceBoosting Angular runtime performance
Boosting Angular runtime performanceNir Kaufman
 
Decorators in js
Decorators in jsDecorators in js
Decorators in jsNir Kaufman
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular componentsNir Kaufman
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive formsNir Kaufman
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tipsNir Kaufman
 

Más de Nir Kaufman (10)

Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniques
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom builders
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developers
 
Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018Redux pattens - JSHeroes 2018
Redux pattens - JSHeroes 2018
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir Kaufman
 
Boosting Angular runtime performance
Boosting Angular runtime performanceBoosting Angular runtime performance
Boosting Angular runtime performance
 
Decorators in js
Decorators in jsDecorators in js
Decorators in js
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular components
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive forms
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tips
 

Último

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 

Último (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 

Solid angular

  • 1. HOW ANGULAR CAN SOLVE ALL YOUR PROBLEMS Nir Kaufman
  • 3. Nir Kaufman - I don’t really need glasses to see - This photo is a photoshop - In reality I’m in color (and fatter) Head of AngularJS Development @ 500Tech
  • 5. “We are not happy with our app. it should be modular, easy to extend and maintain. It’s hard to understand the flow, feels like a spaghetti of presentation and business logic. - frontend team at {{ company.name }}
  • 6. WE NEED A BETTER FRAMEWORK
  • 7.
  • 8.
  • 9. WHAT DO WE NEED?
  • 11. A clean way of organizing your UI code into self-contained, reusable chunks
  • 12. // component controller
 class likeBoxController {
 
 constructor(params) {
 this.chosenValue = params.value;
 }
 
 like() {
 this.chosenValue('like');
 }
 
 dislike() {
 this.chosenValue('dislike');
 }
 }
 
 // component definition
 function likeBoxComponent() {
 return {
 viewModel: likeBoxController,
 template: likeBoxTemplate
 }
 }
 
 // component registration
 ko.components.register('like-widget', likeBoxComponent());
  • 13. // component controller
 class likeBoxController {
 
 constructor() {
 this.chosenValue = null;
 }
 
 like() {
 this.chosenValue = 'like';
 }
 
 dislike() {
 this.chosenValue = 'dislike';
 }
 }
 
 // component definition
 function likeBoxComponent() {
 return {
 controller: likeBoxController,
 scope: { params: ‘=chosenValue' },
 controllerAs: 'LikeBox',
 bindToController: true,
 template: likeBoxTemplate
 }
 }
 
 angular.module('app', [])
 .directive('likeWidget', likeBoxComponent);
  • 14. <div class="like-or-dislike" data-bind="visible: !chosenValue()">
 <button data-bind="click: like">Like it</button>
 <button data-bind="click: dislike">Dislike it</button>
 </div>
 
 <div class="result" data-bind="visible: chosenValue">
 You <strong data-bind="text: chosenValue"></strong> it
 </div> <div class="like-or-dislike" ng-hide="LikeBox.chosenValue">
 <button ng-click="LikeBox.like()">Like it</button>
 <button ng-click="LikeBox.dislike()">Dislike it</button>
 </div>
 
 <div class="result" ng-show="LikeBox.chosenValue">
 You <strong ng-bind="LikeBox.chosenValue"></strong> it
 </div>

  • 15. class LikeWidget extends React.Component {
 
 constructor(props) {
 super(props);
 
 this.state = { chosenValue: null };
 
 this.like = this.like.bind(this);
 this.dislike = this.dislike.bind(this);
 this._likeButtons = this._likeButtons.bind(this)
 }
 
 like() {
 this.setState({
 chosenValue: 'like'
 })
 }
 
 dislike() {
 this.setState({
 chosenValue: 'dislike'
 })
 }
 
 
 _likeButtons() {
 if (this.state.chosenValue) {
 return null
 }
 
 return (
 <div>
 <button onClick={this.like}>Like it</button>
 <button onClick={this.dislike}>Dislike it</button>
 </div>
 )
 }
 
 render() {
 return (
 <div>
 { this._likeButtons() }
 { this.state.chosenValue ?
 <div>You <strong>{ this.state.chosenValue }</strong> it </div> : null}
 </div>
 )
 }
 }
 
 React.render(<LikeWidget/>, document.getElementById('app'));
  • 17. Keep your business logic separate from your user interface
  • 18. class MyViewModel {
 
 constructor() {
 this.products = [
 new Product('Garlic bread'),
 new Product('Pain au chocolat'),
 new Product('Seagull spaghetti', 'like')
 ];
 }
 }
 
 ko.applyBindings(new MyViewModel()); class MyViewModel {
 
 constructor() {
 this.products = [
 new Product('Garlic bread'),
 new Product('Pain au chocolat'),
 new Product('Seagull spaghetti', 'like')
 ];
 }
 }
 
 angular.module('app', [])
 .controller('MyViewModel', MyViewModel);
  • 19. Backbone.Model.extend({
 defaults: {
 coverImage: 'img/placeholder.png',
 title: 'No title',
 author: 'Unknown',
 releaseDate: 'Unknown',
 keywords: 'None'
 }
 }); DS.Model.extend({
 title: DS.attr('No title'),
 author: DS.attr('Unknown'),
 releaseDate: DS.attr('Unknown'),
 keywords: DS.attr('None')
 }); class Book {
 constructor() {
 this.coverImage = 'img/placeholder.png';
 this.title = 'No title';
 this.author = 'Unknown';
 this.releaseDate = 'Unknown';
 this.keywords = 'None';
 }
 }
  • 20. LETS GET TO THE POINT
  • 21. All major frameworks introduce the same concepts. Don’t make a switch for the wrong reasons. Switching to another framework won’t solve your design problems.
  • 23. CONSIDER TYPESCRIPT I used to hate it…
  • 24. SOLID PRINCIPLES Single Responsibility Open / Closed Liskov Substitution Interface Segregation Dependency Inversion
  • 26. A module should have one, and only one reason to change
  • 27. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(($stateProvider, $httpProvider, localStorageServiceProvider) => {
 
 // start routing
 $stateProvider
 .state('dashboard', {
 url: '/dashboard',
 templateUrl: 'states/dashboard/dashboard.html',
 controller: 'DashboardController'
 })
 
 .state('users', {
 url: '/users',
 templateUrl: 'states/users/users.html',
 controller: 'UsersController'
 });
 
 // http configuration
 $httpProvider.useApplyAsync(true);
 $httpProvider.useLegacyPromiseExtensions(false);
 
 $httpProvider.interceptors.push(($log) => {
 return {
 'request': function (config) {
 $log.debug(config);
 return config;
 }
 };
 });
 
 // storage configurations
 localStorageServiceProvider
 .setPrefix('myApp')
 .setStorageType('sessionStorage')
 });
 
 // start engines
 angular.bootstrap(document, ['app']); 4 reasons to change this module: add dependency add new state configure http service configure storage service
  • 28. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(routes)
 .config(http)
 .config(storage)
 
 // start engines
 angular.bootstrap(document, ['app']); export function routes($stateProvider) {
 $stateProvider
 .state('dashboard', {
 url: '/dashboard',
 templateUrl: 'states/dashboard/dashboard.html',
 controller: 'DashboardController'
 })
 
 .state('users', {
 url: '/users',
 templateUrl: 'states/users/users.html',
 controller: 'UsersController'
 });
 }
 routes.ts app.ts export function http ($httpProvider) {
 $httpProvider.useApplyAsync(true);
 $httpProvider.useLegacyPromiseExtensions(false);
 } http.ts export function storage(localStorageServiceProvider) {
 localStorageServiceProvider
 .setPrefix('myApp')
 .setStorageType('sessionStorage')
 } storage.ts
  • 29. // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 .config(routes)
 .config(http)
 .config(storage)
 
 // start engines
 angular.bootstrap(document, ['app']); Are we there yet? 2 reasons to change // module declarations
 angular.module('app', [
 'ui.router',
 'LocalStorageModule',
 'app.states'
 ])
 // start engines
 angular.bootstrap(document, ['app']); 1 responsibility
  • 31. A module should be open for extension, but closed for modification.
  • 32. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 }
 
 show(type) {
 
 switch (type) {
 case 'login':
 this.showLoginModal();
 break;
 case 'info':
 this.showInfoModal();
 break;
 }
 }
 
 showLoginModal() {
 this.modal.open({
 template: 'loginModal.html',
 controller: ‘loginModalController’
 })
 }
 
 showInfoModal() {
 this.modal.open({
 template: 'infoModal.html',
 controller: 'infoModalController'
 })
 }
 } class Controller {
 
 constructor(Modal) {
 this.Modal = Modal;
 }
 
 showLogin(){
 this.Modal.show('login');
 }
 } We need to add new Modals to our system
  • 33. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 this.modals = new Map();
 }
 
 register(type, config) {
 this.modals.set(type, config)
 }
 
 $get() {
 return { show: this.show }
 }
 
 show(type) {
 if(this.modals.has(type)){
 this.modal.open(this.modals.get(type))
 }
 }
 }
 angular.module('app', [])
 .config(ModalProvider => {
 
 ModalProvider.register('lostPassword', {
 template: 'lostPassword.html',
 controller: 'lostPasswordController'
 })
 }); class Controller {
 
 constructor(Modal) {
 this.Modal = Modal;
 }
 
 showLogin(){
 this.Modal.show('lostPassword');
 }
 } Write code that can be extended
  • 35. Child classes should never break the parent class type definitions
  • 39. Many specific interfaces are better than one generic interface
  • 40. I just want to make a copy
  • 41. class LocalStorage {
 private storage;
 private $window;
 
 constructor($window, $q) {
 this.$window = $window;
 }
 
 setStorageType(type:string) {
 if (type === 'local') {
 return this.storage = this.$window.localStorage;
 }
 if (type === 'db') {
 return this.storage = new PouchDB('DB');
 }
 }
 
 setLocalItem(key:string, data) {
 if (this.db) {
 return this.db.put(JSON.parse(data))
 }
 return this.storage.setItem(key, JSON.stringify(data));
 } put(data) {
 this.storage.put(JSON.parse(data))
 } 
 getLocalItem(key:string):string {
 let deferred = this.$q.defer();
 
 if (this.db) {
 this.db.get(key).then( result => deferred.resolve() )
 }
 deferred.resolve(this.storage.getItem());
 return deferred.promise;
 }
 } No client should be forced to depend on methods it doesn’t use
  • 42. class LocalStorage {
 private storage;
 
 constructor($window) {
 this.storage = $window.localStorage;
 }
 
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } class SessionStorage {
 private storage;
 
 constructor($window, $q) {
 this.storage = $window.sessionStorage;
 }
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } localStorage.ts sessionStorage.ts class DBStorage {
 private db;
 
 constructor(PouchDB) {
 this.db = new PouchDB('DB');
 }
 
 put(data) {
 this.db.put(data)
 }
 
 get(id){
 return this.db.get(id);
 }
 } dbStorage.ts UserComponent.ts (client) class UserComponent {
 private storage;
 
 constructor(LocalStorage) {
 this.storage = LocalStorage
 }
 }
  • 44. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • 45. NATIVE API’s ANGULAR 3RD PARTY MODULES APLLICATION CODE INTERFACES Application Layers YOUR MODULES Abstraction Abstraction
  • 46. interface IStorage {
 setItem(key:string, data:any);
 getItem(key:string, data:any);
 } IStorgae.ts UserComponent.ts (client) class UserComponent {
 private storage;
 
 constructor(Storage: IStorage) {
 this.storage = LocalStorage
 }
 } LocalStorage.ts class LocalStorage implements IStorage {
 private storage;
 
 constructor($window) {
 this.storage = $window.localStorage;
 }
 
 setItem(key:string, data) {
 return this.storage.setItem(key, JSON.stringify(data));
 }
 
 getItem(key:string):string {
 return this.storage.getItem();
 }
 } The ‘client’ can work with any kind of storage that implements the IStorage interface
  • 47. export class WelcomeController {
 
 constructor($modal) {
 this.$modal = $modal;
 }
 
 login() {
 let loginModalInstance = this.$modal.open({
 templateUrl: 'states/welcome/login_modal.html',
 keyboard: false,
 backdrop: 'static',
 controller: LoginModalController,
 controllerAs: 'Login'
 });
 
 loginModalInstance.result
 .then(result => console.log(result))
 }
 } Angular Bootstrap Modal export class DashboardController {
 
 constructor($modal) {
 this.$modal = $modal;
 }
 
 showInfo() {
 let infoModalInstance = this.$modal.open({
 templateUrl: 'states/dashboard/info_modal.html',
 keyboard: false,
 backdrop: 'static',
 controller: InfoModalController,
 controllerAs: 'Info'
 });
 
 infoModalInstance.result
 .then(result => console.log(result))
 }
 } What is the problem?
  • 48. class Modal {
 
 constructor($modal) {
 this.modal = $modal;
 this.modals = new Map();
 }
 
 register(type, config) {
 this.modals.set(type, config)
 }
 
 $get() {
 return { show: this.show }
 }
 
 show(type) {
 if(this.modals.has(type)){
 this.modal.open(this.modals.get(type))
 }
 }
 }
 Abstraction without TypeScript
  • 50. DON’T MAKE A SWITCH FOR THE WRONG REASONS
  • 54. Angular ES6 / TypeScript Starters https://github.com/nirkaufman/angular-webpack-starter https://github.com/nirkaufman/angular-webpack-typescript-starter