SlideShare uma empresa Scribd logo
1 de 56
Baixar para ler offline
AngularJS training
Lauri Svan
lauri.svan@sc5.io @laurisvan
(original by kari.heikkinen@sc5.io)
Intro: About the Lecturer
● 15 year battle hardened veteran
● Head of Technology at SC5
● Helsinki Node.js co-founder
● In GitHub & Twitter
● “New school of engineering”
● Knows “why” & some “how” of
AngularJS
Intro: SC5
Yes, we’re hiring!
What is AngularJS
● Developed and maintained by Google
● Current version 1.5 (2.0 in Alpha)
● Good documentation and examples
● 3rd party libraries
● Insanely popular (see Bower, too)
● Easy to learn
● Get things done fast
● “Good enough”
Concepts
Two way data-binding
Dependency Injection (DI)
Application structure
Data driven development!
Recipe for an Angular Application
App Logic:
● 1 Module (the app)
● 1-N Templates for each view
● 1-N Controllers for each view
● 1 Router to toggle between UI states
● 1-N Directives for widgets
● 0-N Resources for each REST API
endpoints
● 0-N Services for inter-app comms &
storing app state
What else?
● Style sheets for app visuals
● Hybrid packaging (optional)
Modules
// Create module without dependencies
angular.module(‘myModule’, [ ] );
// Module with dependency
var app = angular.module(‘myApp’, [ ‘myModule’ ] );
// Get module and define controller
var module = angular.module(‘myModule’);
module.controller( ‘myController’, function($scope) {
$scope.title = ‘myController’;
});
// Declare application in HTML
<div ng-app=”myApp”>
// Declare application to body in javascript
angular.bootstrap( document.body, [‘myApp’] );
Template expressions
Angular template syntax uses double-curly brackets to
bind expression ‘{{ expression }}’.
<span>1+2={{ 1 + 2 }}</span>
{{ ‘Hello’ + ‘ World’ }}
{{ scopeVariable }}
{{ scopeFunction() }}
<img src=”{{ imageUrl }}”>
Controllers
● Controllers allow to interact with a View and Model.
● Is where to hold your presentation logic.
● Controller purpose is to drive Model and View
changes.
● New instance is created for each invocation
Controllers + $scope
Context where the model is stored so that controllers, directives and
expressions can access it.
$scope is a clever Object which is automated bridge between Javascript and
DOM that holds synchronized data.
var app = angular.module(‘myApp’);
app.controller(‘myCtrl’, function( $scope ) {
$scope.title = “MyTitle”;
});
app.controller(‘MySubCtrl’, function( $scope ) {
$scope.content = “MyData”;
});
<div ng-controller=”myCtrl”>
<h1>{{ title }}</h1>
<div ng-controller=”MySubCtrl”>
<p>{{content }}</p>
<span>ref: {{ title }}</span>
</div>
<div>{{content }}</div>
</div>
ControllerAs
New way in 1.3, similar as will be in 2.0
Easier to identify which scope is variable belongs to.
var app = angular.module(‘myApp’);
app.controller(‘myCtrl’, function() {
this.title = “MyTitle”;
});
app.controller(‘MySubCtrl’, function() {
this.content = “MyData”;
});
<div ng-controller=”myCtrl as mainCtrl”>
<h1>{{ mainCtrl.title }}</h1>
<div ng-controller=”MySubCtrl as subCtrl”>
<p>{{ subCtrl.content }}</p>
<span>ref: {{ mainCtrl.title }}</span>
</div>
<div>{{ subCtrl.content }}</div>
</div>
$scope.$watch
Way to react View change in the controller
app.controller(‘myCtrl’, function($scope) {
this.value = ‘Initial value’;
var _this = this;
$scope.$watch(
// return variable to watch (reference)
function() {
return _this.value;
},
// Handler function
function( newValue, oldValue ) {
console.log( oldValue, ‘->’, newValue );
}
);
});
app.controller(‘myCtrl’, function($scope) {
$scope.value = ‘Initial value’;
$scope.$watch(
‘value’,
function( newValue, oldValue ) {
console.log( oldValue, ‘->’, newValue );
}
);
});
W
ithout ControllerAs (1.2.x)
Services
● Use to hold data that persist application lifecycle, as
controllers are discarded when they are removed
from view.
● All services are singletons.
● Controllers access services via dependency injection.
● Three ways of creating services: service, factory, provider
Service
Creates service which will be invoked with ‘new’ to create
instance. (singleton instance)
app.service( ‘MyService’, function() {
this.greet = function() { alert(‘Hello!’); };
this.getText = function() { return ‘Hello!’; };
});
app.controller(‘myCtrl’, function(MyService) {
this.text = MyService.getText();
this.sayHello = function() {
MyService.greet();
}
});
var ServiceClass = function() {
this.color = ‘green’;
}
ServiceClass.prototype.setColor = function(color) {
this.color = color;
}
app.service( ‘MyService’, ServiceClass );
app.controller(‘MyController’, function(MyService) {
this.color = MyService.color;
this.onClick= function(color) {
MyService.setColor(color);
}
});
Factory
Register service by returning service instance object.
Can take advantage of closures.
app.factory( ‘MyService’, function() {
var greetText = “Hello”;
return {
greet: function() { alert(greetText); },
setText: function(text) { greetText = text; }
};
});
// Probably most common way to use factory
app.factory(‘Articles’, function( $resource, Settings ) {
return $resource( Settings.ApiHost + ‘/api/article’ );
}
app.controller(‘myCtrl’, function(MyService) {
this.text = MyService.getText();
this.sayHello = function() {
MyService.greet();
}
});
Providers
Only service definition that can be passed to config()
function.
Use to customize service on configuration phase.
app.provider( ‘MyService’, function() {
this.host = ‘/’;
this.$get = function( $resource ) {
return $resource( this.host + ‘/api/myservice’ );
};
});
app.config( function( MyServiceProvider ) {
if( window.location.host !== ‘example.com‘ )
MyServiceProvider.host = ‘example.com‘;
});
app.controller(‘myCtrl’, function(MyService) {
this.data = MyService.get( {id: 1234} );
});
Value & Constant
angular.module(‘myApp’).value( ‘Settings’, { host: ‘example.com’ } );
angular.module(‘myApp’).constant( ‘Config’, { host: ‘example.com’ } );
angular.module(‘myApp’).config( function(Config, MyServiceProvider ) {
MyServiceProvider.setApiHost( Config.host );
});
angular.module(‘myApp’).controller( ‘myCtrl’, function( Settings, $http ) {
var _this = this;
$http( Settings.host + ‘/api/data’ ).success( function(data) {
_this.data = data;
});
});
Filters
Filters are used for formatting data displayed to the
user.
Primarily used in expressions, but can be used in
controllers and services also.
{{ expression | filter1 | filter2 | ... }}
<span>{{ article.published | date:”yyyy-M-d” }}<span>
<span>{{ item.price | currency:”€” }}</span>
<label>{{ ‘ITEM_PRICE’ | translate }}</label>
<div ng-repeat=”person in persons | orderBy:’lastName’ | limitTo: 10”>{{ person.lastName}}</div>
// TIP: json filter is handy to check what object contains
<pre>{{ obj | json }}</pre>
Built-in filters
● currency - Format currency ( symbol, how many decimal numbers)
● number - To string, how many decimal numbers to use
● date - Format Date to string, use locale format as default
● json - Object to JSON string
● lowercase - Converts string to lowercase
● uppercase - Converts string to uppercase
● filter - select subset of array
● limitTo - creates new array with specified number of elements
● orderBy - Order array by the expression
Custom filter
app.filter( ‘translate’, function( LocalizationService ) {
return function( str ) {
return LocalizationService.getTranslation( str );
};
});
app.constant( ‘Settings’, { dateFormat: ‘d.M.yyyy’ } );
app.filter( ‘formatDate’, function( $filter, Settings ) {
var dateFilter = $filter.get(‘date’);
return function( date ) {
return dateFilter( date, Settings.dateFormat );
}
});
app.filter( ‘fullName’, function() {
return function( person ) { return person.firstName + ‘ ‘ + person.lastName; };
});
Directives
A Directive can be anything, it can either provide powerful logic to an
existing specific element, or be an element itself and provide an injected
template with powerful logic inside.
Directives are markers on a DOM element (such as an attribute, element
name, comment or CSS class) that tell AngularJS's HTML compiler to attach
a specified behavior to that DOM element or even transform the DOM
element and its children.
Angular comes with a set of built-in directives:
ng-model, ng-repeat, ng-show/ng-hide, ng-if, ng-click, ng-disabled, ng-
mouseover, ng-blur, ng-src/ng-href, ng-class, ng-switch, ng-bind, ng-view ….
Custom directives 1
Directives can match attribute name, tag name,
comments or class name. Or restricted only to match
some of them
<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>
Directives can emulate Shadow DOM behaviour with
option transclude
<my-element>
Hi there!
</my-element>
Custom directives 2
app.controller(‘myCtrl, function() {
this.person = { firstName: ‘John’, lastName: ‘Doe’ };
});
app.directive(‘person’, function() {
return {
template: ‘{{person.lastName}}, {{person.firstName}}’
};
});
<div ng-controller=”myCtrl”>
<h1>Hello <person></person></h1>,
<p>...</p>
</div>
Custom directives 3
app.directive(‘article’, function() {
return {
restrict: ‘EA’,
scope: { article: ‘=article’ },
templateUrl: ‘article.html
};
});
app.controller(‘myCtrl’, function() {
this.article = {
title: ‘Headline’,
content: ‘Lore ipsum’,
published: 1234554543543,
author: ‘John Doe’
}
});
article.html:
<article>
<header>
<h1>{{article.title}}</h1>
<p>Posted by {{ article.author }}</p>
<p>{{ article.published | date: ‘d.M.yyyy’ }}</p>
</header>
<p>{{ article.content }}</p>
</article>
index.html:
<article=”myCtrl.article”></article>
<div article=”MyCtrl.article”></div>
Custom directives 4
app.directive(‘article’, function() {
return {
restrict: ‘E’,
scope: { data: ‘=data },
bindToController: true,
templateUrl: ‘article.html,
controlelrAs, ‘article’,
controller: function() {
this.addComment = function(msg) {
this.data.comments.push(msg);
this.data.$save();
}
}
};
});
<article>
<header>
<h1>{{article.data.title}}</h1>
</header>
<p>{{ article.data.content }}</p>
<div class=comments>
<ul>
<li ng-repeat=”comment in article.data.comments”>{{ comment }}</li>
</ul>
<input ng-model=”newComment”/>
<button ng-click=”article.addComment(newComment)”>Send</button>
</div>
</article>
Custom directive 5 (transclude)
app.directive(“hideable”, function() {
return {
replace: true,
transclude: true,
template: [
‘<div ng-init=”hide=false”>’,
’<button ng-click=”hide=!hide”>Show/Hide</button>’,
‘<div ng-transclude ng-hide=”hide”></div>’,
‘</div>’
].join(‘’)
};
});
<div>
<h1> {{ title }} </h1>
<hideable>
<h2>{{ subTitle }}</h2>
<p>{{ content }}</p>
</hideable>
</div>
<div>
<h1> {{ title }} </h1>
<div ng-init=”hidden=false”>
<button ng-click=”hidden=!hidden”>Show/Hide</button>
<div ng-hide=”hidden”>
<h2>{{ subTitle }}</h2>
<p>{{ content }}</p>
</div>
</div>
</div>
Directive configuration
priority: 0,
template: '<div></div>', // 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',
bindToController: false,
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
// link: function postLink( ... ) { ... }
Forms
Form and controls provide validation services, so that
the user can be notified of invalid input.
This provides a better user experience, because the user
gets instant feedback on how to correct the error.
Forms
<form name=”myFrom” novalidate>
<label>Email:</label>
<input type=”email” name=”email” ng-model=”user.email” required />
<label>Password:</label>
<input type=”password” name=”password” ng-model=”user.password” required minlength=”8” />
<div ng-messages=”myForm.password.$error”>
<div ng-message=”required”>Password is required</div>
<div ng-message=”minlength”>Password is too short</div>
</div>
<button ng-disabled=”myForm.$invalid”>Submit</button>
</form>
Form CSS classes
● ng-valid: the model is valid
● ng-invalid: the model is invalid
● ng-valid-[key]: for each valid key added by $setValidity
● ng-invalid-[key]: for each invalid key added by $setValidity
● ng-pristine: the control hasn't been interacted with yet
● ng-dirty: the control has been interacted with
● ng-touched: the control has been blurred
● ng-untouched: the control hasn't been blurred
● ng-pending: any $asyncValidators are unfulfilled
Form CSS class example
<form name=”myFrom” novalidate>
<label>Email:</label>
<input
type=”email”
name=”email”
ng-model=”user.email”
required />
</form>
<style type="text/css">
form input.ng-invalid.ng-dirty {
outline-color: #FA787E;
}
</style>
Form validators
HTML5 input validators are built-in to Angular:
number, email, required, url, time, date, ..
Create own validators with directives:
<input name=”pwd”
type=”password
ng-model=”user.password”
required
minlength=”8”
validate-password-characters />
<div ng-messages=”myFrom.pwd.$error”>
<div ng-message=”required”>Password is required</div>
<div ng-message=”minlength”>Password is too short</div>
<div ng-message=”passwordCharacters”>Your password must contain a numeric, uppercase and ..
</div>
</div>
Custom validator
app.directive('validatePasswordCharacters', function() {
var REQUIRED_PATTERNS = [
/d+/, //numeric values
/[a-z]+/, //lowercase values
/[A-Z]+/, //uppercase values
/W+/, //special characters
/^S+$/ //no whitespace allowed
];
return {
require : 'ngModel',
link : function($scope, element, attrs, ngModel) {
ngModel.$validators.passwordCharacters = function(value) {
var status = true;
angular.forEach(REQUIRED_PATTERNS, function(pattern) {
status = status && pattern.test(value);
});
return status;
};
}
}
});
Async validator
angular.module(‘myApp’).directive(‘validateUsernameAvailable’, function($http) {
return {
require: ‘ngModel’,
link: function( scope, element, attr, ngModel ) {
ngModel.$asyncValidators.usernameAvailable = function(username) {
return $http.get(‘/api/username-exists?username=’ + username );
}
}
};
});
<input type=”text” name=”myUsername” validate-username-available />
<div ng-if="myForm.myUsername.$pending"> Checking Username… </div>
<div ng-if="myForm.myUsername.$error.usernameAvailable"> User name is in use </div>
<button ng-disabled=”!myForm.$valid”>Submit</button>
ngModelOptions
Validation and specially async validation may cause too
many calls for validation.
With ngModelOptions you can control when ngModel is
updated and validators are executed.
// Update when leaving input element
<input ng-model=”value” ng-model-options=”{ updateOn:’blur’ }” required />
// Update only when no changes in 500ms or immediately when leaving element
<input ng-model=”username” ng-model-options=”{ debounce: { default: 500, blur: 0 } }”
required validate-username-available />
Events
Angular scope have built-in event framework.
● $on - listen to event
● $emit - send event to upwards (self and parent
scopes)
● $broadcast - send event to downwards (self / child
scopes)
<div ng-controller="EventCtrl as parentCtrl" ng-scope>
<div ng-controller="EventCtrl as childCtrl1" ng-scope>
<div ng-controller="EventCtrl as subChildCtrl" ng-scope></div>
</div>
<div ng-controller="EventCtrl as childCtrl2" ng-scope>
</div>
</div>
$broadcast $send
Angular extension modules
● ngRoute - Routing and deeplinking
● ngResource - RESTful services
● ngAnimate - Support for JS, CSS transitions and
animations hooks
● ngSanitize - Bind HTML content safe way
● ngTouch - Touch events
● ngMessages - Enhanced support to show messages
ngRoute
To create routing for your Angular application include
ngRoute module and defined routes in config()-function.
angular.module(´myApp´, [´ngRoute´]).config(
function( $routeProvider, $locationProvider ) {
$routeProvider
.when('/', {
templateUrl: 'main.html',
controller: ´mainController´
}).
.when('/page1', {
templateUrl: page1.html',
controller: ´page1Controller´
}).
.otherwise({ redirectTo: ´/´ });
$locationProvider.html5Mode(true);
});
index.html:
<body>
<div ng-view> Route content will be here </div>
main.html:
<h1>main page</h1>
<a href=”/page”>goto to sub page</a>
page.html:
<h1>Page1 </h1>
<a href=”/”>back to main page</a>
ngRoute - resolve content
angular.module('myApp').config( function($routeProvider) {
$routeProvider.
when("/article/:id", {
templateUrl: 'article.html',
controller: 'ArticleCtrl',
controllerAs: ‘articleCtrl’,
resolve: {
article: function($resource, $route, $q, $location) {
var Article = $resource(‘/api/article/:id’);
var request = Article.get({id: $route.current.params.id});
request.$promise.catch( function() {
$location.path(‘/notfound’);
$location.replace();
});
return request.$promise;
}
}
});
});
angular.module(‘myApp’)
.controller( ‘articleCtrl’,
function( article ) {
this.data = article;
});
ngResource
Factory service which creates a resource object that lets
you to interact RESTful API.
Makes data handling object oriented.
var User = $resource(
‘/api/user/:id’,
{ id: ‘@_id’ },
{
update: { method: ‘PUT’ }
});
var person = new User({
firstName: ‘John’,
lastName:’doe’
});
person.$save();
person.lastName = ‘Doe’;
person.$update();
var person = new User({
firstName: ‘John’,
lastName:’doe’
});
person.$save(); // POST: ‘/api/user’
person.lastName = ‘Doe’;
person.$update(); // PUT: ‘/api/user/1’
// GET: ’/api/user?firstName=John’
var users = User.query({ firstName: ‘John });
var john = User.get({ id: 1234 }, function() {
john.lastLogin = new Date();
john.$update();
});
ngResource
Default configuration:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
ngResource
var Article = $resource(‘/api/article/:id’, { id: ‘@_id’ }, {
recent: {
method: ‘GET’,
isArray: true,
cache: true, // use http cache for method
params: { limit: 10, latest: true }
}
});
// GET: /api/article?limit=10&latest=true&type=news
var latestArticles = Article.$latest( { type: ‘news’ } );
latestArticles.$promise
.success( function() {
// articles loaded
})
.catch( function() {
// request failed
});
ngAnimate
Adds animation hooks for common directives such as
ngRepeat, ngView and ngShow.
Also pays attention to CSS class changes with ngClass by
triggering add and remove hooks.
When change is triggered it places state CSS class, like
ng-hide, and end state ng-hide-active. And after
animation is ended it removes those classes
ngShow animate
<button ng-click=”hide=!hide”>Show/hide</button>
<div class=”animate” ng-show=”hide”>
Shown/hide with animation
</div>
<style>
.animate { opacity: 1; }
.animate.ng-hide { opacity: 0; }
.animate.ng-hide-add,
.animate.ng-hide-remove {
-webkit-transition: 1s linear all;
transition: 1s linear all;
}
</style>
JS animation with jQuery
angular.module('myApp',['ngAnimate']).animation('.animate', function() {
return {
beforeAddClass: function(element, className, done) {
if( className === 'ng-hide' )
element.animate({ opacity: 0 }, 500, done );
else
done();
},
removeClass: function(element, className, done) {
if( className === 'ng-hide' )
element.css({ opacity: 0 }).animate({ opacity: 1}, 500, done );
else
done();
}
}
})
Testing
AngularJS is designed that applications are testable.
Dependency Injection makes testing easier, by allowing
inject mock instead of real module.
Unit testing with Karma
my-ctrl.js:
angular.module('myApp',[])
.controller('myCtrl', function( $http ) {
var _this = this;
$http.get('/api/data').success(function(data) {
_this.data = data;
});
this.isOk = function() {
return this.data && this.data.ok;
}
});
my-ctrl.spec.js:
describe('controller:myCtrl', function() {
beforeEach( module('myApp') );
it('should fetch data from server and return ok',
inject(function($controller, $httpBackend) {
$httpBackend
.when('GET', '/api/data')
.respond({ ok: true });
$httpBackend.expectGET('/api/data');
var ctrl = $controller( 'myCtrl' );
expect(ctrl.isOk()).toBe(false);
$httpBackend.flush();
expect(ctrl.isOk()).toBe(true);
})
);
});
Dependency Injection in testing
it('should fetch data from server and return ok', inject(function($controller) {
var ctrlCB;
var myHttpMock = {
get: function() {
return {
success: function(cb) { ctrlCB= cb; }
};
}
}
var ctrl = $controller( 'myCtrl', { $http: myHttpMock } );
expect(ctrlCB).not.toBe(undefined);
cb( { ok: true } );
expect(ctrl.isOk()).toBe( true );
}));
End-to-end testing with protractor
describe('password view', function() {
it('should show error when too short input', function() {
browser.get('http://localhost:63342/angular-training/protractor/index.html');
element(by.model('user.password')).sendKeys('test');
var messages = element(by.id('password.error'));
expect(messages.getText()).toContain('short');
element(by.model('user.password')).sendKeys('test12345ABC-');
element(by.buttonText(‘save’)).click();
});
});
Best practices
● Design UI/HTML first!
Create HTML first and then just add functionality with
Angular. Style guide + UI mock-ups
● Avoid using $scope directly
By eliminating usage of $scope, code is closer to 2.0
style
● Avoid using ng-controller in HTML
Use through route or directives, do not add them
directly.
● Testing is easy!
Write tests for your code / site
Best practices
● If repeating elements in HTML, create directive for them
● Create services and use $resource to access server APIs
● Do not format data in the controllers, which will be displayed in the
view, instead use filter. Example, localisation, date/time, currency, etc.
Create filters that do it for you, and you can then modify those filters
and reflect changes to whole site.
● Avoid long lists which contains lots of bind data, that can cause
performance issues. Use paging to limit elements, if data changes in
page, otherwise use one-time binding (Angular 1.3), or libraries like
‘bindonce’ for Angular 1.2
● If you are binding without dot, you are probably doing something
wrong. {{ name }} = BAD, {{ user.name }} = GOOD
● Keep code structured
Caveats
● 2000 watches is considered as saturation point, after that page
rendering may seem slow
● Use directive isolated scope only when needed. Specially with
transclude, it can cause problems not to be able to access variables
● Namespace
Modules does not add namespace for functions. Plan function naming
(controller/service/directive/filter)
● Dependency Injection and javascript minify
DI breaks when minified. Declare in array syntax or use
ngAnnote/ngMin
● When using 3rd party libraries etc, remember to call $apply to get
changes render to page
Tools & Utilities for AngularJS
Boilerplates
https://github.com/SC5/gulp-bobrsass-boilerplate/tree/angularjs
https://github.com/DaftMonk/generator-angular-fullstack
Testing:
http://angular.github.io/protractor/#/
http://karma-runner.github.io/0.12/index.html
http://www.ng-newsletter.com/advent2013/#!/day/19
Build and minification:
https://github.com/olov/ng-annotate
More about AngularJS
Community in Helsinki capital area
https://www.facebook.com/groups/helsinkijs/
http://frontend.fi/
AngularJS Primer
https://www.airpair.com/angularjs/posts/angularjs-tutorial
https://thinkster.io/angulartutorial/a-better-way-to-learn-angularjs/
http://lostechies.com/gabrielschenker/2013/12/05/angularjspart-1/
Blogs that have good information about AngularJS:
http://www.yearofmoo.com/
http://www.jvandemo.com/
Good reads:
http://sc5.io/posts/how-to-implement-loaders-for-an-angularjs-app
http://teropa.info/blog/2014/11/01/why-i-think-angular-2-will-still-be-angular.html
Conclusion and discussion
What did we learn?
Discussion about AngularJS
Test setup
● Install Node.js for test server
http://nodejs.org/download/
● Download and extract training examples
https://docs.google.com/a/sc5.io/uc?
authuser=0&id=0B_18Pna_ughFNWVZaUV1amV6bjA&export=download
● Go to exercises folder and execute commands
> npm install
> npm start
● Open local web server with browser
http://localhost:3000/

Mais conteúdo relacionado

Mais procurados

Opinionated AngularJS
Opinionated AngularJSOpinionated AngularJS
Opinionated AngularJSprabhutech
 
Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Paco de la Cruz
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silexMichele Orselli
 
Durable functions
Durable functionsDurable functions
Durable functions명신 김
 
Implementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfImplementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfMichele Orselli
 
Implementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsImplementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsMichele Orselli
 
"Inside The AngularJS Directive Compiler" by Tero Parviainen
"Inside The AngularJS Directive Compiler" by Tero Parviainen"Inside The AngularJS Directive Compiler" by Tero Parviainen
"Inside The AngularJS Directive Compiler" by Tero ParviainenFwdays
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.AngularEvan Schultz
 
Introduction to Angular js
Introduction to Angular jsIntroduction to Angular js
Introduction to Angular jsMustafa Gamal
 
Angular 2 KTS
Angular 2 KTSAngular 2 KTS
Angular 2 KTSJohn Vall
 
The battle of Protractor and Cypress - RunIT Conference 2019
The battle of Protractor and Cypress - RunIT Conference 2019The battle of Protractor and Cypress - RunIT Conference 2019
The battle of Protractor and Cypress - RunIT Conference 2019Ludmila Nesvitiy
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directivesAlexe Bogdan
 
Building Android apps with Parse
Building Android apps with ParseBuilding Android apps with Parse
Building Android apps with ParseDroidConTLV
 
Auto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendAuto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendSven Efftinge
 
Testowanie JavaScript
Testowanie JavaScriptTestowanie JavaScript
Testowanie JavaScriptTomasz Bak
 

Mais procurados (20)

Opinionated AngularJS
Opinionated AngularJSOpinionated AngularJS
Opinionated AngularJS
 
Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30) Azure Durable Functions (2019-03-30)
Azure Durable Functions (2019-03-30)
 
Server side data sync for mobile apps with silex
Server side data sync for mobile apps with silexServer side data sync for mobile apps with silex
Server side data sync for mobile apps with silex
 
Durable functions
Durable functionsDurable functions
Durable functions
 
Implementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconfImplementing data sync apis for mibile apps @cloudconf
Implementing data sync apis for mibile apps @cloudconf
 
Implementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile AppsImplementing Server Side Data Synchronization for Mobile Apps
Implementing Server Side Data Synchronization for Mobile Apps
 
"Inside The AngularJS Directive Compiler" by Tero Parviainen
"Inside The AngularJS Directive Compiler" by Tero Parviainen"Inside The AngularJS Directive Compiler" by Tero Parviainen
"Inside The AngularJS Directive Compiler" by Tero Parviainen
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.Angular
 
Introduction to Angular js
Introduction to Angular jsIntroduction to Angular js
Introduction to Angular js
 
Angular 2 KTS
Angular 2 KTSAngular 2 KTS
Angular 2 KTS
 
Solid angular
Solid angularSolid angular
Solid angular
 
The battle of Protractor and Cypress - RunIT Conference 2019
The battle of Protractor and Cypress - RunIT Conference 2019The battle of Protractor and Cypress - RunIT Conference 2019
The battle of Protractor and Cypress - RunIT Conference 2019
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Angular custom directives
Angular custom directivesAngular custom directives
Angular custom directives
 
AngularJS Basics with Example
AngularJS Basics with ExampleAngularJS Basics with Example
AngularJS Basics with Example
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
 
Building Android apps with Parse
Building Android apps with ParseBuilding Android apps with Parse
Building Android apps with Parse
 
Auto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with XtendAuto-GWT : Better GWT Programming with Xtend
Auto-GWT : Better GWT Programming with Xtend
 
Testowanie JavaScript
Testowanie JavaScriptTestowanie JavaScript
Testowanie JavaScript
 

Destaque

Machine Learning Using Cloud Services
Machine Learning Using Cloud ServicesMachine Learning Using Cloud Services
Machine Learning Using Cloud ServicesSC5.io
 
Securing the client side web
Securing the client side webSecuring the client side web
Securing the client side webSC5.io
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesRainer Stropek
 
Angular js best practice
Angular js best practiceAngular js best practice
Angular js best practiceMatteo Scandolo
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
AngularJS application architecture
AngularJS application architectureAngularJS application architecture
AngularJS application architectureGabriele Falace
 

Destaque (9)

Machine Learning Using Cloud Services
Machine Learning Using Cloud ServicesMachine Learning Using Cloud Services
Machine Learning Using Cloud Services
 
AngularJS
AngularJSAngularJS
AngularJS
 
Securing the client side web
Securing the client side webSecuring the client side web
Securing the client side web
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
Angular js-crash-course
Angular js-crash-courseAngular js-crash-course
Angular js-crash-course
 
AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
 
Angular js best practice
Angular js best practiceAngular js best practice
Angular js best practice
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS application architecture
AngularJS application architectureAngularJS application architecture
AngularJS application architecture
 

Semelhante a AngularJS training covers concepts like data binding, directives

AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosAngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosLearnimtactics
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)Chris Clarke
 
Angular Presentation
Angular PresentationAngular Presentation
Angular PresentationAdam Moore
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Angular workshop - Full Development Guide
Angular workshop - Full Development GuideAngular workshop - Full Development Guide
Angular workshop - Full Development GuideNitin Giri
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications Juliana Lucena
 
Custom AngularJS Directives
Custom AngularJS DirectivesCustom AngularJS Directives
Custom AngularJS Directivesyprodev
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directivesyprodev
 
AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)Nitya Narasimhan
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs WorkshopRan Wahle
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014Ran Wahle
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS BasicsRavi Mone
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 

Semelhante a AngularJS training covers concepts like data binding, directives (20)

AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Angular js
Angular jsAngular js
Angular js
 
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle StudiosAngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
AngularJs Superheroic JavaScript MVW Framework Services by Miracle Studios
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)
 
Angular Presentation
Angular PresentationAngular Presentation
Angular Presentation
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Angular workshop - Full Development Guide
Angular workshop - Full Development GuideAngular workshop - Full Development Guide
Angular workshop - Full Development Guide
 
AngularJS Workshop
AngularJS WorkshopAngularJS Workshop
AngularJS Workshop
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
Angular js
Angular jsAngular js
Angular js
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
Angular js
Angular jsAngular js
Angular js
 
Custom AngularJS Directives
Custom AngularJS DirectivesCustom AngularJS Directives
Custom AngularJS Directives
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directives
 
AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)
 
angularJs Workshop
angularJs WorkshopangularJs Workshop
angularJs Workshop
 
AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014AngularJs Workshop SDP December 28th 2014
AngularJs Workshop SDP December 28th 2014
 
AngularJS Basics
AngularJS BasicsAngularJS Basics
AngularJS Basics
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 

Mais de SC5.io

AWS Machine Learning & Google Cloud Machine Learning
AWS Machine Learning & Google Cloud Machine LearningAWS Machine Learning & Google Cloud Machine Learning
AWS Machine Learning & Google Cloud Machine LearningSC5.io
 
Transfer learning with Custom Vision
Transfer learning with Custom VisionTransfer learning with Custom Vision
Transfer learning with Custom VisionSC5.io
 
Practical AI for Business: Bandit Algorithms
Practical AI for Business: Bandit AlgorithmsPractical AI for Business: Bandit Algorithms
Practical AI for Business: Bandit AlgorithmsSC5.io
 
Decision trees & random forests
Decision trees & random forestsDecision trees & random forests
Decision trees & random forestsSC5.io
 
Bandit Algorithms
Bandit AlgorithmsBandit Algorithms
Bandit AlgorithmsSC5.io
 
Miten design-muutosjohtaminen hyödyttää yrityksiä?
Miten design-muutosjohtaminen hyödyttää yrityksiä?Miten design-muutosjohtaminen hyödyttää yrityksiä?
Miten design-muutosjohtaminen hyödyttää yrityksiä?SC5.io
 
Engineering HTML5 Applications for Better Performance
Engineering HTML5 Applications for Better PerformanceEngineering HTML5 Applications for Better Performance
Engineering HTML5 Applications for Better PerformanceSC5.io
 
2013 10-02-backbone-robots-aarhus
2013 10-02-backbone-robots-aarhus2013 10-02-backbone-robots-aarhus
2013 10-02-backbone-robots-aarhusSC5.io
 
2013 10-02-html5-performance-aarhus
2013 10-02-html5-performance-aarhus2013 10-02-html5-performance-aarhus
2013 10-02-html5-performance-aarhusSC5.io
 
2013 04-02-server-side-backbone
2013 04-02-server-side-backbone2013 04-02-server-side-backbone
2013 04-02-server-side-backboneSC5.io
 
Building single page applications
Building single page applicationsBuilding single page applications
Building single page applicationsSC5.io
 

Mais de SC5.io (11)

AWS Machine Learning & Google Cloud Machine Learning
AWS Machine Learning & Google Cloud Machine LearningAWS Machine Learning & Google Cloud Machine Learning
AWS Machine Learning & Google Cloud Machine Learning
 
Transfer learning with Custom Vision
Transfer learning with Custom VisionTransfer learning with Custom Vision
Transfer learning with Custom Vision
 
Practical AI for Business: Bandit Algorithms
Practical AI for Business: Bandit AlgorithmsPractical AI for Business: Bandit Algorithms
Practical AI for Business: Bandit Algorithms
 
Decision trees & random forests
Decision trees & random forestsDecision trees & random forests
Decision trees & random forests
 
Bandit Algorithms
Bandit AlgorithmsBandit Algorithms
Bandit Algorithms
 
Miten design-muutosjohtaminen hyödyttää yrityksiä?
Miten design-muutosjohtaminen hyödyttää yrityksiä?Miten design-muutosjohtaminen hyödyttää yrityksiä?
Miten design-muutosjohtaminen hyödyttää yrityksiä?
 
Engineering HTML5 Applications for Better Performance
Engineering HTML5 Applications for Better PerformanceEngineering HTML5 Applications for Better Performance
Engineering HTML5 Applications for Better Performance
 
2013 10-02-backbone-robots-aarhus
2013 10-02-backbone-robots-aarhus2013 10-02-backbone-robots-aarhus
2013 10-02-backbone-robots-aarhus
 
2013 10-02-html5-performance-aarhus
2013 10-02-html5-performance-aarhus2013 10-02-html5-performance-aarhus
2013 10-02-html5-performance-aarhus
 
2013 04-02-server-side-backbone
2013 04-02-server-side-backbone2013 04-02-server-side-backbone
2013 04-02-server-side-backbone
 
Building single page applications
Building single page applicationsBuilding single page applications
Building single page applications
 

Último

A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012rehmti665
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一Fs
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一Fs
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhimiss dipika
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMartaLoveguard
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一Fs
 

Último (20)

A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
定制(Lincoln毕业证书)新西兰林肯大学毕业证成绩单原版一比一
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 
Contact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New DelhiContact Rya Baby for Call Girls New Delhi
Contact Rya Baby for Call Girls New Delhi
 
Magic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptxMagic exist by Marta Loveguard - presentation.pptx
Magic exist by Marta Loveguard - presentation.pptx
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
 

AngularJS training covers concepts like data binding, directives

  • 1. AngularJS training Lauri Svan lauri.svan@sc5.io @laurisvan (original by kari.heikkinen@sc5.io)
  • 2. Intro: About the Lecturer ● 15 year battle hardened veteran ● Head of Technology at SC5 ● Helsinki Node.js co-founder ● In GitHub & Twitter ● “New school of engineering” ● Knows “why” & some “how” of AngularJS
  • 4. What is AngularJS ● Developed and maintained by Google ● Current version 1.5 (2.0 in Alpha) ● Good documentation and examples ● 3rd party libraries ● Insanely popular (see Bower, too) ● Easy to learn ● Get things done fast ● “Good enough”
  • 5. Concepts Two way data-binding Dependency Injection (DI) Application structure Data driven development!
  • 6. Recipe for an Angular Application App Logic: ● 1 Module (the app) ● 1-N Templates for each view ● 1-N Controllers for each view ● 1 Router to toggle between UI states ● 1-N Directives for widgets ● 0-N Resources for each REST API endpoints ● 0-N Services for inter-app comms & storing app state What else? ● Style sheets for app visuals ● Hybrid packaging (optional)
  • 7. Modules // Create module without dependencies angular.module(‘myModule’, [ ] ); // Module with dependency var app = angular.module(‘myApp’, [ ‘myModule’ ] ); // Get module and define controller var module = angular.module(‘myModule’); module.controller( ‘myController’, function($scope) { $scope.title = ‘myController’; }); // Declare application in HTML <div ng-app=”myApp”> // Declare application to body in javascript angular.bootstrap( document.body, [‘myApp’] );
  • 8. Template expressions Angular template syntax uses double-curly brackets to bind expression ‘{{ expression }}’. <span>1+2={{ 1 + 2 }}</span> {{ ‘Hello’ + ‘ World’ }} {{ scopeVariable }} {{ scopeFunction() }} <img src=”{{ imageUrl }}”>
  • 9. Controllers ● Controllers allow to interact with a View and Model. ● Is where to hold your presentation logic. ● Controller purpose is to drive Model and View changes. ● New instance is created for each invocation
  • 10. Controllers + $scope Context where the model is stored so that controllers, directives and expressions can access it. $scope is a clever Object which is automated bridge between Javascript and DOM that holds synchronized data. var app = angular.module(‘myApp’); app.controller(‘myCtrl’, function( $scope ) { $scope.title = “MyTitle”; }); app.controller(‘MySubCtrl’, function( $scope ) { $scope.content = “MyData”; }); <div ng-controller=”myCtrl”> <h1>{{ title }}</h1> <div ng-controller=”MySubCtrl”> <p>{{content }}</p> <span>ref: {{ title }}</span> </div> <div>{{content }}</div> </div>
  • 11. ControllerAs New way in 1.3, similar as will be in 2.0 Easier to identify which scope is variable belongs to. var app = angular.module(‘myApp’); app.controller(‘myCtrl’, function() { this.title = “MyTitle”; }); app.controller(‘MySubCtrl’, function() { this.content = “MyData”; }); <div ng-controller=”myCtrl as mainCtrl”> <h1>{{ mainCtrl.title }}</h1> <div ng-controller=”MySubCtrl as subCtrl”> <p>{{ subCtrl.content }}</p> <span>ref: {{ mainCtrl.title }}</span> </div> <div>{{ subCtrl.content }}</div> </div>
  • 12. $scope.$watch Way to react View change in the controller app.controller(‘myCtrl’, function($scope) { this.value = ‘Initial value’; var _this = this; $scope.$watch( // return variable to watch (reference) function() { return _this.value; }, // Handler function function( newValue, oldValue ) { console.log( oldValue, ‘->’, newValue ); } ); }); app.controller(‘myCtrl’, function($scope) { $scope.value = ‘Initial value’; $scope.$watch( ‘value’, function( newValue, oldValue ) { console.log( oldValue, ‘->’, newValue ); } ); }); W ithout ControllerAs (1.2.x)
  • 13. Services ● Use to hold data that persist application lifecycle, as controllers are discarded when they are removed from view. ● All services are singletons. ● Controllers access services via dependency injection. ● Three ways of creating services: service, factory, provider
  • 14. Service Creates service which will be invoked with ‘new’ to create instance. (singleton instance) app.service( ‘MyService’, function() { this.greet = function() { alert(‘Hello!’); }; this.getText = function() { return ‘Hello!’; }; }); app.controller(‘myCtrl’, function(MyService) { this.text = MyService.getText(); this.sayHello = function() { MyService.greet(); } }); var ServiceClass = function() { this.color = ‘green’; } ServiceClass.prototype.setColor = function(color) { this.color = color; } app.service( ‘MyService’, ServiceClass ); app.controller(‘MyController’, function(MyService) { this.color = MyService.color; this.onClick= function(color) { MyService.setColor(color); } });
  • 15. Factory Register service by returning service instance object. Can take advantage of closures. app.factory( ‘MyService’, function() { var greetText = “Hello”; return { greet: function() { alert(greetText); }, setText: function(text) { greetText = text; } }; }); // Probably most common way to use factory app.factory(‘Articles’, function( $resource, Settings ) { return $resource( Settings.ApiHost + ‘/api/article’ ); } app.controller(‘myCtrl’, function(MyService) { this.text = MyService.getText(); this.sayHello = function() { MyService.greet(); } });
  • 16. Providers Only service definition that can be passed to config() function. Use to customize service on configuration phase. app.provider( ‘MyService’, function() { this.host = ‘/’; this.$get = function( $resource ) { return $resource( this.host + ‘/api/myservice’ ); }; }); app.config( function( MyServiceProvider ) { if( window.location.host !== ‘example.com‘ ) MyServiceProvider.host = ‘example.com‘; }); app.controller(‘myCtrl’, function(MyService) { this.data = MyService.get( {id: 1234} ); });
  • 17. Value & Constant angular.module(‘myApp’).value( ‘Settings’, { host: ‘example.com’ } ); angular.module(‘myApp’).constant( ‘Config’, { host: ‘example.com’ } ); angular.module(‘myApp’).config( function(Config, MyServiceProvider ) { MyServiceProvider.setApiHost( Config.host ); }); angular.module(‘myApp’).controller( ‘myCtrl’, function( Settings, $http ) { var _this = this; $http( Settings.host + ‘/api/data’ ).success( function(data) { _this.data = data; }); });
  • 18. Filters Filters are used for formatting data displayed to the user. Primarily used in expressions, but can be used in controllers and services also. {{ expression | filter1 | filter2 | ... }} <span>{{ article.published | date:”yyyy-M-d” }}<span> <span>{{ item.price | currency:”€” }}</span> <label>{{ ‘ITEM_PRICE’ | translate }}</label> <div ng-repeat=”person in persons | orderBy:’lastName’ | limitTo: 10”>{{ person.lastName}}</div> // TIP: json filter is handy to check what object contains <pre>{{ obj | json }}</pre>
  • 19. Built-in filters ● currency - Format currency ( symbol, how many decimal numbers) ● number - To string, how many decimal numbers to use ● date - Format Date to string, use locale format as default ● json - Object to JSON string ● lowercase - Converts string to lowercase ● uppercase - Converts string to uppercase ● filter - select subset of array ● limitTo - creates new array with specified number of elements ● orderBy - Order array by the expression
  • 20. Custom filter app.filter( ‘translate’, function( LocalizationService ) { return function( str ) { return LocalizationService.getTranslation( str ); }; }); app.constant( ‘Settings’, { dateFormat: ‘d.M.yyyy’ } ); app.filter( ‘formatDate’, function( $filter, Settings ) { var dateFilter = $filter.get(‘date’); return function( date ) { return dateFilter( date, Settings.dateFormat ); } }); app.filter( ‘fullName’, function() { return function( person ) { return person.firstName + ‘ ‘ + person.lastName; }; });
  • 21. Directives A Directive can be anything, it can either provide powerful logic to an existing specific element, or be an element itself and provide an injected template with powerful logic inside. Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler to attach a specified behavior to that DOM element or even transform the DOM element and its children. Angular comes with a set of built-in directives: ng-model, ng-repeat, ng-show/ng-hide, ng-if, ng-click, ng-disabled, ng- mouseover, ng-blur, ng-src/ng-href, ng-class, ng-switch, ng-bind, ng-view ….
  • 22. Custom directives 1 Directives can match attribute name, tag name, comments or class name. Or restricted only to match some of them <my-dir></my-dir> <span my-dir="exp"></span> <!-- directive: my-dir exp --> <span class="my-dir: exp;"></span> Directives can emulate Shadow DOM behaviour with option transclude <my-element> Hi there! </my-element>
  • 23. Custom directives 2 app.controller(‘myCtrl, function() { this.person = { firstName: ‘John’, lastName: ‘Doe’ }; }); app.directive(‘person’, function() { return { template: ‘{{person.lastName}}, {{person.firstName}}’ }; }); <div ng-controller=”myCtrl”> <h1>Hello <person></person></h1>, <p>...</p> </div>
  • 24. Custom directives 3 app.directive(‘article’, function() { return { restrict: ‘EA’, scope: { article: ‘=article’ }, templateUrl: ‘article.html }; }); app.controller(‘myCtrl’, function() { this.article = { title: ‘Headline’, content: ‘Lore ipsum’, published: 1234554543543, author: ‘John Doe’ } }); article.html: <article> <header> <h1>{{article.title}}</h1> <p>Posted by {{ article.author }}</p> <p>{{ article.published | date: ‘d.M.yyyy’ }}</p> </header> <p>{{ article.content }}</p> </article> index.html: <article=”myCtrl.article”></article> <div article=”MyCtrl.article”></div>
  • 25. Custom directives 4 app.directive(‘article’, function() { return { restrict: ‘E’, scope: { data: ‘=data }, bindToController: true, templateUrl: ‘article.html, controlelrAs, ‘article’, controller: function() { this.addComment = function(msg) { this.data.comments.push(msg); this.data.$save(); } } }; }); <article> <header> <h1>{{article.data.title}}</h1> </header> <p>{{ article.data.content }}</p> <div class=comments> <ul> <li ng-repeat=”comment in article.data.comments”>{{ comment }}</li> </ul> <input ng-model=”newComment”/> <button ng-click=”article.addComment(newComment)”>Send</button> </div> </article>
  • 26. Custom directive 5 (transclude) app.directive(“hideable”, function() { return { replace: true, transclude: true, template: [ ‘<div ng-init=”hide=false”>’, ’<button ng-click=”hide=!hide”>Show/Hide</button>’, ‘<div ng-transclude ng-hide=”hide”></div>’, ‘</div>’ ].join(‘’) }; }); <div> <h1> {{ title }} </h1> <hideable> <h2>{{ subTitle }}</h2> <p>{{ content }}</p> </hideable> </div> <div> <h1> {{ title }} </h1> <div ng-init=”hidden=false”> <button ng-click=”hidden=!hidden”>Show/Hide</button> <div ng-hide=”hidden”> <h2>{{ subTitle }}</h2> <p>{{ content }}</p> </div> </div> </div>
  • 27. Directive configuration priority: 0, template: '<div></div>', // 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', bindToController: false, 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 // link: function postLink( ... ) { ... }
  • 28. Forms Form and controls provide validation services, so that the user can be notified of invalid input. This provides a better user experience, because the user gets instant feedback on how to correct the error.
  • 29. Forms <form name=”myFrom” novalidate> <label>Email:</label> <input type=”email” name=”email” ng-model=”user.email” required /> <label>Password:</label> <input type=”password” name=”password” ng-model=”user.password” required minlength=”8” /> <div ng-messages=”myForm.password.$error”> <div ng-message=”required”>Password is required</div> <div ng-message=”minlength”>Password is too short</div> </div> <button ng-disabled=”myForm.$invalid”>Submit</button> </form>
  • 30. Form CSS classes ● ng-valid: the model is valid ● ng-invalid: the model is invalid ● ng-valid-[key]: for each valid key added by $setValidity ● ng-invalid-[key]: for each invalid key added by $setValidity ● ng-pristine: the control hasn't been interacted with yet ● ng-dirty: the control has been interacted with ● ng-touched: the control has been blurred ● ng-untouched: the control hasn't been blurred ● ng-pending: any $asyncValidators are unfulfilled
  • 31. Form CSS class example <form name=”myFrom” novalidate> <label>Email:</label> <input type=”email” name=”email” ng-model=”user.email” required /> </form> <style type="text/css"> form input.ng-invalid.ng-dirty { outline-color: #FA787E; } </style>
  • 32. Form validators HTML5 input validators are built-in to Angular: number, email, required, url, time, date, .. Create own validators with directives: <input name=”pwd” type=”password ng-model=”user.password” required minlength=”8” validate-password-characters /> <div ng-messages=”myFrom.pwd.$error”> <div ng-message=”required”>Password is required</div> <div ng-message=”minlength”>Password is too short</div> <div ng-message=”passwordCharacters”>Your password must contain a numeric, uppercase and .. </div> </div>
  • 33. Custom validator app.directive('validatePasswordCharacters', function() { var REQUIRED_PATTERNS = [ /d+/, //numeric values /[a-z]+/, //lowercase values /[A-Z]+/, //uppercase values /W+/, //special characters /^S+$/ //no whitespace allowed ]; return { require : 'ngModel', link : function($scope, element, attrs, ngModel) { ngModel.$validators.passwordCharacters = function(value) { var status = true; angular.forEach(REQUIRED_PATTERNS, function(pattern) { status = status && pattern.test(value); }); return status; }; } } });
  • 34. Async validator angular.module(‘myApp’).directive(‘validateUsernameAvailable’, function($http) { return { require: ‘ngModel’, link: function( scope, element, attr, ngModel ) { ngModel.$asyncValidators.usernameAvailable = function(username) { return $http.get(‘/api/username-exists?username=’ + username ); } } }; }); <input type=”text” name=”myUsername” validate-username-available /> <div ng-if="myForm.myUsername.$pending"> Checking Username… </div> <div ng-if="myForm.myUsername.$error.usernameAvailable"> User name is in use </div> <button ng-disabled=”!myForm.$valid”>Submit</button>
  • 35. ngModelOptions Validation and specially async validation may cause too many calls for validation. With ngModelOptions you can control when ngModel is updated and validators are executed. // Update when leaving input element <input ng-model=”value” ng-model-options=”{ updateOn:’blur’ }” required /> // Update only when no changes in 500ms or immediately when leaving element <input ng-model=”username” ng-model-options=”{ debounce: { default: 500, blur: 0 } }” required validate-username-available />
  • 36. Events Angular scope have built-in event framework. ● $on - listen to event ● $emit - send event to upwards (self and parent scopes) ● $broadcast - send event to downwards (self / child scopes) <div ng-controller="EventCtrl as parentCtrl" ng-scope> <div ng-controller="EventCtrl as childCtrl1" ng-scope> <div ng-controller="EventCtrl as subChildCtrl" ng-scope></div> </div> <div ng-controller="EventCtrl as childCtrl2" ng-scope> </div> </div> $broadcast $send
  • 37. Angular extension modules ● ngRoute - Routing and deeplinking ● ngResource - RESTful services ● ngAnimate - Support for JS, CSS transitions and animations hooks ● ngSanitize - Bind HTML content safe way ● ngTouch - Touch events ● ngMessages - Enhanced support to show messages
  • 38. ngRoute To create routing for your Angular application include ngRoute module and defined routes in config()-function. angular.module(´myApp´, [´ngRoute´]).config( function( $routeProvider, $locationProvider ) { $routeProvider .when('/', { templateUrl: 'main.html', controller: ´mainController´ }). .when('/page1', { templateUrl: page1.html', controller: ´page1Controller´ }). .otherwise({ redirectTo: ´/´ }); $locationProvider.html5Mode(true); }); index.html: <body> <div ng-view> Route content will be here </div> main.html: <h1>main page</h1> <a href=”/page”>goto to sub page</a> page.html: <h1>Page1 </h1> <a href=”/”>back to main page</a>
  • 39. ngRoute - resolve content angular.module('myApp').config( function($routeProvider) { $routeProvider. when("/article/:id", { templateUrl: 'article.html', controller: 'ArticleCtrl', controllerAs: ‘articleCtrl’, resolve: { article: function($resource, $route, $q, $location) { var Article = $resource(‘/api/article/:id’); var request = Article.get({id: $route.current.params.id}); request.$promise.catch( function() { $location.path(‘/notfound’); $location.replace(); }); return request.$promise; } } }); }); angular.module(‘myApp’) .controller( ‘articleCtrl’, function( article ) { this.data = article; });
  • 40. ngResource Factory service which creates a resource object that lets you to interact RESTful API. Makes data handling object oriented. var User = $resource( ‘/api/user/:id’, { id: ‘@_id’ }, { update: { method: ‘PUT’ } }); var person = new User({ firstName: ‘John’, lastName:’doe’ }); person.$save(); person.lastName = ‘Doe’; person.$update(); var person = new User({ firstName: ‘John’, lastName:’doe’ }); person.$save(); // POST: ‘/api/user’ person.lastName = ‘Doe’; person.$update(); // PUT: ‘/api/user/1’ // GET: ’/api/user?firstName=John’ var users = User.query({ firstName: ‘John }); var john = User.get({ id: 1234 }, function() { john.lastLogin = new Date(); john.$update(); });
  • 41. ngResource Default configuration: { 'get': {method:'GET'}, 'save': {method:'POST'}, 'query': {method:'GET', isArray:true}, 'remove': {method:'DELETE'}, 'delete': {method:'DELETE'} };
  • 42. ngResource var Article = $resource(‘/api/article/:id’, { id: ‘@_id’ }, { recent: { method: ‘GET’, isArray: true, cache: true, // use http cache for method params: { limit: 10, latest: true } } }); // GET: /api/article?limit=10&latest=true&type=news var latestArticles = Article.$latest( { type: ‘news’ } ); latestArticles.$promise .success( function() { // articles loaded }) .catch( function() { // request failed });
  • 43. ngAnimate Adds animation hooks for common directives such as ngRepeat, ngView and ngShow. Also pays attention to CSS class changes with ngClass by triggering add and remove hooks. When change is triggered it places state CSS class, like ng-hide, and end state ng-hide-active. And after animation is ended it removes those classes
  • 44. ngShow animate <button ng-click=”hide=!hide”>Show/hide</button> <div class=”animate” ng-show=”hide”> Shown/hide with animation </div> <style> .animate { opacity: 1; } .animate.ng-hide { opacity: 0; } .animate.ng-hide-add, .animate.ng-hide-remove { -webkit-transition: 1s linear all; transition: 1s linear all; } </style>
  • 45. JS animation with jQuery angular.module('myApp',['ngAnimate']).animation('.animate', function() { return { beforeAddClass: function(element, className, done) { if( className === 'ng-hide' ) element.animate({ opacity: 0 }, 500, done ); else done(); }, removeClass: function(element, className, done) { if( className === 'ng-hide' ) element.css({ opacity: 0 }).animate({ opacity: 1}, 500, done ); else done(); } } })
  • 46. Testing AngularJS is designed that applications are testable. Dependency Injection makes testing easier, by allowing inject mock instead of real module.
  • 47. Unit testing with Karma my-ctrl.js: angular.module('myApp',[]) .controller('myCtrl', function( $http ) { var _this = this; $http.get('/api/data').success(function(data) { _this.data = data; }); this.isOk = function() { return this.data && this.data.ok; } }); my-ctrl.spec.js: describe('controller:myCtrl', function() { beforeEach( module('myApp') ); it('should fetch data from server and return ok', inject(function($controller, $httpBackend) { $httpBackend .when('GET', '/api/data') .respond({ ok: true }); $httpBackend.expectGET('/api/data'); var ctrl = $controller( 'myCtrl' ); expect(ctrl.isOk()).toBe(false); $httpBackend.flush(); expect(ctrl.isOk()).toBe(true); }) ); });
  • 48. Dependency Injection in testing it('should fetch data from server and return ok', inject(function($controller) { var ctrlCB; var myHttpMock = { get: function() { return { success: function(cb) { ctrlCB= cb; } }; } } var ctrl = $controller( 'myCtrl', { $http: myHttpMock } ); expect(ctrlCB).not.toBe(undefined); cb( { ok: true } ); expect(ctrl.isOk()).toBe( true ); }));
  • 49. End-to-end testing with protractor describe('password view', function() { it('should show error when too short input', function() { browser.get('http://localhost:63342/angular-training/protractor/index.html'); element(by.model('user.password')).sendKeys('test'); var messages = element(by.id('password.error')); expect(messages.getText()).toContain('short'); element(by.model('user.password')).sendKeys('test12345ABC-'); element(by.buttonText(‘save’)).click(); }); });
  • 50. Best practices ● Design UI/HTML first! Create HTML first and then just add functionality with Angular. Style guide + UI mock-ups ● Avoid using $scope directly By eliminating usage of $scope, code is closer to 2.0 style ● Avoid using ng-controller in HTML Use through route or directives, do not add them directly. ● Testing is easy! Write tests for your code / site
  • 51. Best practices ● If repeating elements in HTML, create directive for them ● Create services and use $resource to access server APIs ● Do not format data in the controllers, which will be displayed in the view, instead use filter. Example, localisation, date/time, currency, etc. Create filters that do it for you, and you can then modify those filters and reflect changes to whole site. ● Avoid long lists which contains lots of bind data, that can cause performance issues. Use paging to limit elements, if data changes in page, otherwise use one-time binding (Angular 1.3), or libraries like ‘bindonce’ for Angular 1.2 ● If you are binding without dot, you are probably doing something wrong. {{ name }} = BAD, {{ user.name }} = GOOD ● Keep code structured
  • 52. Caveats ● 2000 watches is considered as saturation point, after that page rendering may seem slow ● Use directive isolated scope only when needed. Specially with transclude, it can cause problems not to be able to access variables ● Namespace Modules does not add namespace for functions. Plan function naming (controller/service/directive/filter) ● Dependency Injection and javascript minify DI breaks when minified. Declare in array syntax or use ngAnnote/ngMin ● When using 3rd party libraries etc, remember to call $apply to get changes render to page
  • 53. Tools & Utilities for AngularJS Boilerplates https://github.com/SC5/gulp-bobrsass-boilerplate/tree/angularjs https://github.com/DaftMonk/generator-angular-fullstack Testing: http://angular.github.io/protractor/#/ http://karma-runner.github.io/0.12/index.html http://www.ng-newsletter.com/advent2013/#!/day/19 Build and minification: https://github.com/olov/ng-annotate
  • 54. More about AngularJS Community in Helsinki capital area https://www.facebook.com/groups/helsinkijs/ http://frontend.fi/ AngularJS Primer https://www.airpair.com/angularjs/posts/angularjs-tutorial https://thinkster.io/angulartutorial/a-better-way-to-learn-angularjs/ http://lostechies.com/gabrielschenker/2013/12/05/angularjspart-1/ Blogs that have good information about AngularJS: http://www.yearofmoo.com/ http://www.jvandemo.com/ Good reads: http://sc5.io/posts/how-to-implement-loaders-for-an-angularjs-app http://teropa.info/blog/2014/11/01/why-i-think-angular-2-will-still-be-angular.html
  • 55. Conclusion and discussion What did we learn? Discussion about AngularJS
  • 56. Test setup ● Install Node.js for test server http://nodejs.org/download/ ● Download and extract training examples https://docs.google.com/a/sc5.io/uc? authuser=0&id=0B_18Pna_ughFNWVZaUV1amV6bjA&export=download ● Go to exercises folder and execute commands > npm install > npm start ● Open local web server with browser http://localhost:3000/