Henk Bakker
It's a structural framework for dynamic web apps
that's easy to maintain, in a fast and testable way.
<!DOCTYPE html>
<html ng-app>
<head>
<script src="js/angular.min.js"></script>
</head>
<body>
<form>
<label>Your name?</label>
<input type="text" ng-model="name" placeholder="Your name?">
</form>
<h3>My name is {{ name }}!</h3>
</body>
</html>
$scope is an object that refers to the application model.
It connects the View and the Controller
myController.js
function MyController($scope) {
$scope.name = 'Henk Bakker';
}
myView.html
<form ng-controller="MyController">
<input type="text" ng-model="name">
</form>
The controller is a function that augment the $scope object.
It's used to add a value or to add a behavior to the $scope.
function TodoCtrl($scope) {
$scope.todos = [
{ text: 'Learn AngularJS', done: true },
{ text: 'Create an App', done: false }
];
$scope.addTodo = function () {
$scope.todos.push({ text: $scope.todoText, done: false });
$scope.todoText = '';
};
};
The templates are simply HTML5.
All the presentation logic of the app must be in there.
<div ng-controller="TodoCtrl">
<ul>
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span>{{ todo.text }}</span>
</li>
</ul>
<form ng-submit="addTodo()">
<input type="text" ng-model="todoText">
<button type="submit">Add</button>
</form>
</div>
Most templating systems bind data in only one direction: they merge template and model components together into a view
Two-way data binding is the automatic synchronization
of data between the model and view.
When a new $scope is created, it's added
as a child of it's parent $scope.
MyControllers.js
function ParentController($scope) {
$scope.person = {
name : 'Henk Bakker',
helloText: ''
};
};
function ChildController($scope) {
$scope.sayHello = function () {
$scope.person.helloText = "Hi " + $scope.person.name;
}
};
MyView.html
<div ng-controller="ParentController">
<form ng-controller="ChildController">
<input type="text" ng-model="person.name" placeholder="Name">
<button ng-click="sayHello()">Say hello</button>
</form>
<p>{{ person.helloText }}</p>
</div>
person.helloText = {{ person.helloText }}
Injctable objects that carry out specific tasks.
Provide a way to separate concerns and re-use code.
The $http service makes easier to integration with external APIs.
Main methods: .get, .post, .put, .delete, .jsonp
$http.get('http://address-of.the/api')
.success(successCallback)
.error(errorCallback);
$http.post('http://address-of.the/api', data)
.success(successCallback)
.error(errorCallback);
function BeerController($scope, $http) {
$scope.makeRequest = function () {
$http.jsonp('http://api.openbeerdatabase.com/v1/beers.json')
.success(function (data, status) {
$scope.beers = data.beers;
})
.error(function () {
$scope.beers = [{ name: "No beer for you :(" }]
});
};
};
<div ng-controller="BeerController">
<ul>
<li ng-repeat="beer in beers | limitTo:15">
{{ beer.name }} - {{ beer.brewery.name }}
</li>
</ul>
<button ng-click="makeRequest()">Get beers</button>
</div>
Angular modules declaratively specify
how an application should be bootstrapped.
var app = angular.module('myApp', ['third-part-module']);
app.config(function () { ... });
app.controller('myController', ...);
app.service('myService', ...);
<html ng-app="myApp">
...
</html>
In a more complex app you can use the $routeProvider service, to define which controller and template will be loaded in each path.
var app = angular.module('myApp');
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller :'mainController', templateUrl :'/views/index.html'
})
.when('/newPost/', {
controller :'newPostController', templateUrl :'/views/newPost.html'
})
.when('/posts/:id', {
controller :'postsController', templateUrl :'/views/posts.html'
})
.otherwise({ redirectTo : '/' });
});
"Teach new tricks to the HTML"
All the attributes that begin with "ng" are AngularJS directives.
How to use directives
<!doctype html>
<html ng-app="myApp">
<head>
<script src="../js/angular.min.js"></script>
</head>
<body>
<ul ng-controller="myListController">
<li ng-repeat="item in items">
{{ item.name }}
</li>
</ul>
</body>
</html>
You can also create you own directive.
var app = angular.module('myApp');
app.directive('myDirective', function () {
return {
restrict: 'EA',
link: function ($scope, element) {
element.text('Text from directive');
}
};
});
<my-directive> </my-directive>
<div my-directive> </div>
var app = angular.module('myApp');
app.directive('myDirective', function () {
return {
restrict: 'E',
replace: true,
template: ''
link: function ($scope, element) {
element.text('Text from directive');
}
};
});
<my-directive> </my-directive>
<h1 class="title">Text from directive</h1>
A framework to be easily tested
describe('Testing Controller', function () {
var ctrl, scope;
beforeEach(angular.mock.module('myApp'));
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
ctrl = $controller('myController', { $scope: scope });
}));
it('should exist a controller called myController', function() {
expect(scope).not.toBeUndefined();
});
});
describe('Grocery list', function () {
beforeEach(function () {
browser().navigateTo('/');
});
it('filters the grocery list based on the search query', function() {
expect(repeater('.groceries li').count()).toBe(5);
input('query').enter('b');
expect(repeater('.groceries li').count()).toBe(3);
input('query').enter('blueberry');
expect(repeater('.groceries li').count()).toBe(1);
});
});