Seven major AngularJS articles.
Great resource to learn about AngularJS.
What's the problem?
HTML and JavaScript are too coupled together
Too much of a mix between AJAX and traditional HTTP page refreshes
Too dependent on how the backend works
Testing usually becomes secondary
Code is too brittle
Too much work overall
MVC frameworks are a great approach to this
Smaller amounts of HTML & JavaScript code required
Provide some level of testing and organization
Backend-agnostic HTML code
AngularJS does this and more...
Powerful Front-end JavaScript MVC Framework
Extends HTML to build complex web applications
Organizes JavaScript code into reusable modules
Uses routes and views to structure your application
Dependency-injected code allows for easy testing
Dynamic templating using standard HTML tags and data bindings
Modular JavaScript code
Dependency injection (services and factories)
Controllers and URL Routing
Multi-level data scoping
Animation hooks
Setup a basic HTML index.html file
<html ng-app>
<body>
Hello {{ myName }}
<script type="text/javascript" src="angular.js"></script>
</body>
</html>
<html ng-app="myApp">
<body>
<div ng-controller="AppCtrl">
<input type="text" ng-model="myName" />
Hello {{ myName }}
</div>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript">
var app = angular.module('myApp', [])
app.controller('AppCtrl', function($scope) {
$scope.myName = '...';
});
</script>
</body>
</html>
All AngularJS JavaScript code is stored in modules
var app = angular.module('superModule', ['otherModule', 'anotherModule']);
And a module is attached to a page
<html ng-app="superModule"> ... </html>
Modules are used to define services, controllers, directives and filters
Each module member is a constructor which can inject other services
app.factory('myValues', function() {
return function() {
return [1,2,3,4,5,6];
};
});
app.filter('skipFirstValue', function() {
return function(data) {
return data.slice(1);
}
});
app.run(function($rootScope, myValues, skipFirstValueFilter) {
//this is called when the page is loaded
$rootScope.values = skipFirstValue(myValues());
});
The scope is the glue between JavaScript and HTML in AngularJS
app.controller('AppCtrl', function($scope) {
$scope.totalApples = 0;
$scope.moreApples = function() {
$scope.totalApples++;
}
});
Anything placed on the $scope object can be referenced in HTML
Hello, so far I have {{ totalApples }} apples.
Think of the scope as the memory for your HTML
$rootScope is the base scope of all scopes
A child scope is a new container within a scope
AngularJS may create additional child scopes to isolate data within a template
<div ng-controller="AppCtrl as outer">
<div ng-controller="InnerCtrl as inner" ng-init="value='1'">
{{ inner.value }}
</div>
<div ng-controller="InnerCtrl as inner" ng-init="value='2'">
{{ inner.value }}
</div>
</div>
Controllers are defined inside of a module like all other services
app.controller('AppCtrl', function($scope) { ... });
And they can be referenced in HTML using ng-controller.
Or within routes...
Routes are enabled when ngRoute is set as a dependency
And then $routeProvider is used to define the routing
var app = angular.module('myApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider.when('/home', {
controller : 'HomeCtrl',
templateUrl : 'home.html'
});
$routeProvider.when('/contact', {
controller : 'ContactCtrl',
templateUrl : 'contact.html'
});
});
app.controller('HomeCtrl', function() { });
app.controller('ContactCtrl', function() { });
To display views, use the ng-view element
<html ng-app="myApp">
<body>
<div ng-view></div>
<script type="text/javascript" src="angular.js"></script>
</body>
</html>
Place this in your index.html file
AngularJS provides series of predefined HTML components
These components reduce much of the JavaScript required to make HTML appear dynamic
ngRepeat renders a list of items from a scope member
var app = angular.module('myApp', []);
app.controller('ColorsCtrl', function($scope) {
$scope.colors = 'red,green,blue,orange,yellow,purple,gray'.split(',');
$scope.tooManyColors = function() {
return $scope.colors.length >= 5;
};
});
<div ng-controller="ColorsCtrl">
This application has too many colors!
<div ng-repeat="color in colors">
{{ color }}
</div>
</div>
ngInclude works to render content like ngView does
<div ng-controller="AppCtrl as app">
<select ng-model="app.templateValue">
<option value="'frame1.html'">Frame 1</option>
<option value="'frame2.html'">Frame 2</option>
</select>
<div ng-include="app.templateValue"></div>
</div>
ngShow and ngHide show and hide an element on screen
<div ng-controller="AppCtrl as app">
<button ng-click="app.showMe=true">
Show
</em>
<button ng-click="app.showMe=false">
Hide
</em>
<div ng-show="app.showMe">
I am visible...
</div>
</div>
Use $http to perform an AJAX request
var app = angular.module('myApp', []);
app.controller('ColorsCtrl', function($scope, $http) {
$scope.colors = $http.get('/api/colors.json');
});
The scope will automatically update itself when $http returns gets a response
Use $resource to push and pull data from a RESTful API
var app = angular.module('myApp', ['ngResource']);
app.factory('Color', function($resource) {
return $resource('/api/colors', {
id : '@id'
}, {
find : { method : 'GET' },
query : { method : 'GET', isArray: true },
create : { method : 'POST' },
update : { method : 'PUT' },
destroy : { method : 'DELETE' }
});
});
app.controller('ColorsCtrl', function($scope, Color) {
$scope.colors = Color.query();
});
Special custom components in HTML
<div my-special-element></div>
Which are then handled in JavaScript via DOM manipulation
app.directive('mySpecialElement', function() {
return function($scope, element, attrs) {
element.bind('click', function() {
alert('clicked');
});
};
});
Something more advanced...
app.directive('mySpecialElement', function() {
return {
scope : { times : 0 },
template : 'You have been clicked {{ times }}',
controller : function($scope) {
$scope.$on('clicked', function() {
$scope.times++;
});
},
link : function($scope, element, attrs) {
element.bind('click', function() {
$scope.$apply(function() {
$scope.$emit('clicked');
});
});
}
}
});
Unit testing is available via the angular-mocks.js file
Both Jasmine and Mocha are supported
describe('Test colors', function() {
it('should have a green color by default',
inject(function($rootScope, $controller) {
var ctrl = $controller('AppCtrl', {
$scope : $rootScope
});
expect(ctrl.colors.indexOf('green')).toBe(true);
}));
});
Supported currently by using angular-scenario.js and soon to be with Protractor.
Uses a working web URL and performs assertions using a Jasmine-style matcher system
describe('Test Home Page', function() {
it('should have a welcome message on the home page', function() {
browser().navigateTo('#/home');
expect(browser().location().path()).toBe("/home");
expect(element('[ng-view]').html()).toContain('welcome to the home page!');
});
});
Supported with the latest release of AngularJS (v1.2-rc2)
Include the ngAnimate module as a dependency for your app module.
var app = angular.module('myApp', ['ngRoute', 'ngAnimate','ngResource']);
Animations work with ng-* directives automatically via CSS and/or JavaScript hooks
CSS3 Transitions + CSS3 Keyframe Animations are automatically triggered and rendered
Just include a CSS class on the ngView element
<div ng-view class="my-view"></div>
.my-view.ng-enter, .mv-view.ng-leave {
transition:1s linear all;
}
.my-view.ng-leave.ng-leave-active {
.my-view.ng-enter {
opacity:0;
}
.my-view.ng-enter.ng-enter-active {
.my-view.ng-leave {
opacity:1;
}
JavaScript callbacks are available for more advanced animations
Include a CSS class just as before and map that to a JavaScript animation
app.animation('.my-view', function() {
return {
enter : function(element, done) {
jQuery(element).animate({
opacity:1
}, done);
},
leave : function(element, done) {
jQuery(element).animate({
opacity:0
}, done);
}
};
});
Here is a full-fledged demo of AngularJS with just about all the features from the presentation
And the Github repo for that is located at:
The $promise API
Form Validation
$scope Events
More about testing
angularjs.org - Docs + Guides
egghead.io - The best AngularJS screencasts website
https://github.com/jmcunningham/AngularJS-Learning - A great list of helpful AngularJS resources
yearofmoo.com - Helpful articles on AngularJS (Testing and Animations)
Thank you for making this possible
Feel free to contact me via matias@yearofmoo.com