- Resources
- General
- Data Binding
- Scope
- Directives
- Component
- Controller
- Services
- Deep Linking
- Form Validation
- Server Communication
- Localization
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
</head>
<body>
<div>
<label>Name:</label>
<input type="text" ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{yourName}}!</h1>
</div>
</body>
</html>
Data-binding is an automatic way of updating the view whenever the model changes, as well as updating the model whenever the view changes. This is awesome because it eliminates DOM manipulation from the list of things you have to worry about.
Simple example is seen in hello world.
Accomplished using ng-model directive and {{ }}, ng-repeat and others.
Templates are written with HTML that contains Angular-specific elements and attributes. Angular combines the template with information from the model and controller to render the dynamic view that a user sees in the browser.
These are the types of Angular elements and attributes you can use:
- Directive — An attribute or element that augments an existing DOM element or represents a reusable DOM component.
- Markup — The double curly brace notation {{ }} to bind expressions to elements is built-in Angular markup.
- Filter — Formats data for display.
- Form controls — Validates user input.
In a simple app, the template consists of HTML, CSS, and Angular
directives contained in just one HTML file (usually index.html).
In a more complex app, you can display multiple views within one main
page using "partials" – segments of template located in separate HTML
files. You can use the ngView directive to load partials based on
configuration passed to the $route service.
Compiler is an Angular service which traverses the DOM looking for attributes. The compilation process happens in two phases. Compile: traverse the DOM and collect all of the directives. The result is a linking function. Link: combine the directives with a scope and produce a live view. Any changes in the scope model are reflected in the view, and any user interactions with the view are reflected in the scope model. This makes the scope model the single source of truth.
A directive is a behavior which should be triggered when specific HTML constructs are encountered during the compilation process. The directives can be placed in element names, attributes, class names, as well as comments.
A directive is just a function which executes when the compiler encounters it in the DOM. See directive API for in-depth documentation on how to write directives.
More info here.
The second kind of new markup are the double curly braces {{ expression | filter }}: When the compiler encounters this markup, it will replace it with the evaluated value of the markup. An expression in a template is a JavaScript-like code snippet that allows Angular to read and write variables. Note that those variables are not global variables.
More info here.
A filter formats the value of an expression for display to the user. They can be used in view templates, controllers or services and it is easy to define your own filter.
Scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events.
Scopes provide APIs ($watch) to observe model mutations. Scopes provide APIs ($apply) to propagate any model changes through the system into the view from outside of the "Angular realm" (controllers, services, Angular event handlers).
Each Angular application has exactly one root scope, but may have several child scopes. The application can have multiple scopes, because some directives create new child scopes (refer to directive documentation to see which directives create new scopes). When new scopes are created, they are added as children of their parent scope.
To examine the scope in the debugger:
-
Right click on the element of interest in your browser and select 'inspect element'. You should see the browser debugger with the element you clicked on highlighted.
-
The debugger allows you to access the currently selected element in the console as $0 variable.
-
To retrieve the associated scope in console execute: angular.element($0).scope() or just type $scope
Scopes can propagate events in similar fashion to DOM events. The event can be broadcasted to the scope children or emitted to scope parents.
More info here.
Directives is a unique and powerful feature available only in Angular. Directives let you invent new HTML syntax, specific to your application.
Angular normalizes an element's tag and attribute name to determine which elements match which directives. We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel). However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case forms, typically using dash-delimited attributes on DOM elements (e.g. ng-model). The normalization process is as follows: Strip x- and data- from the front of the element/attributes. Convert the :, -, or _-delimited name to camelCase.
<div ng-controller="Controller">
Hello <input ng-model='name'> <hr/>
<span ng-bind="name"></span> <br/>
<span ng:bind="name"></span> <br/>
<span ng_bind="name"></span> <br/>
<span data-ng-bind="name"></span> <br/>
<span x-ng-bind="name"></span> <br/>
$compile can match directives based on element names, attributes, class names, as well as comments. All of the Angular-provided directives match attribute name, tag name, comments, or class name.
<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>
Much like controllers, directives are registered on modules. To register a directive, you use the module.directive API. module.directive takes the normalized directive name followed by a factory function. This factory function should return an object with the different options to tell $compile how the directive should behave when matched.
| Name | Description |
|---|---|
| ngJq | Use this directive to force the angular.element library. This should be used to force either jqLite by leaving ng-jq blank or setting the name of the jquery variable under window (eg. jQuery). |
| ngApp | Use this directive to auto-bootstrap an AngularJS application. The ngApp directive designates the root element of the application and is typically placed near the root element of the page - e.g. on the <body> or <html> tags. |
| a | Modifies the default behavior of the html A tag so that the default action is prevented when the href attribute is empty. |
| ngHref | Using Angular markup like {{hash}} in an href attribute will make the link go to the wrong URL if the user clicks it before Angular has a chance to replace the {{hash}} markup with its value. Until Angular replaces the markup the link will be broken and will most likely return a 404 error. The ngHref directive solves this problem. |
| ngSrc | Using Angular markup like {{hash}} in a src attribute doesn't work right: The browser will fetch from the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. The ngSrc directive solves this problem. |
| ngSrcset | Using Angular markup like {{hash}} in a srcset attribute doesn't work right: The browser will fetch from the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. The ngSrcset directive solves this problem. |
| ngDisabled | This directive sets the disabled attribute on the element if the expression inside ngDisabled evaluates to truthy. |
| ngChecked | Sets the checked attribute on the element, if the expression inside ngChecked is truthy. |
| ngReadonly | Sets the readOnly attribute on the element, if the expression inside ngReadonly is truthy. |
| ngSelected | Sets the selected attribute on the element, if the expression inside ngSelected is truthy. |
| ngOpen | Sets the open attribute on the element, if the expression inside ngOpen is truthy. |
| ngForm | Nestable alias of form directive. HTML does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a sub-group of controls needs to be determined. |
| form | Directive that instantiates FormController. |
| textarea | HTML textarea element control with angular data-binding. The data-binding and validation properties of this element are exactly the same as those of the input element. |
| input | HTML input element control. When used together with ngModel, it provides data-binding, input state control, and validation. Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers. |
| ngValue | Binds the given expression to the value of <option> or input[radio], so that when the element is selected, the ngModel of that element is set to the bound value. |
| ngBind | The ngBind attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes. |
| ngBindTemplate | The ngBindTemplate directive specifies that the element text content should be replaced with the interpolation of the template in the ngBindTemplate attribute. Unlike ngBind, the ngBindTemplate can contain multiple {{ }} expressions. This directive is needed since some HTML elements (such as TITLE and OPTION) cannot contain SPAN elements. |
| ngBindHtml | Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default, the resulting HTML content will be sanitized using the $sanitize service. To utilize this functionality, ensure that $sanitize is available, for example, by including ngSanitize in your module's dependencies (not in core Angular). In order to use ngSanitize in your module's dependencies, you need to include "angular-sanitize.js" in your application. |
| ngChange | Evaluate the given expression when the user changes the input. The expression is evaluated immediately, unlike the JavaScript onchange event which only triggers at the end of a change (usually, when the user leaves the form element or presses the return key). |
| ngClass | The ngClass directive allows you to dynamically set CSS classes on an HTML element by databinding an expression that represents all classes to be added. |
| ngClassOdd | The ngClassOdd and ngClassEven directives work exactly as ngClass, except they work in conjunction with ngRepeat and take effect only on odd (even) rows. |
| ngClassEven | The ngClassOdd and ngClassEven directives work exactly as ngClass, except they work in conjunction with ngRepeat and take effect only on odd (even) rows. |
| ngCloak | The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display. |
| ngController | The ngController directive attaches a controller class to the view. This is a key aspect of how angular supports the principles behind the Model-View-Controller design pattern. |
| ngCsp | Angular has some features that can break certain CSP (Content Security Policy) rules. |
| ngClick | The ngClick directive allows you to specify custom behavior when an element is clicked. |
| ngDblclick | The ngDblclick directive allows you to specify custom behavior on a dblclick event. |
| ngMousedown | The ngMousedown directive allows you to specify custom behavior on mousedown event. |
| ngMouseup | Specify custom behavior on mouseup event. |
| ngMouseover | Specify custom behavior on mouseover event. |
| ngMouseenter | Specify custom behavior on mouseenter event. |
| ngMouseleave | Specify custom behavior on mouseleave event. |
| ngMousemove | Specify custom behavior on mousemove event. |
| ngKeydown | Specify custom behavior on keydown event. |
| ngKeyup | Specify custom behavior on keyup event. |
| ngKeypress | Specify custom behavior on keypress event. |
| ngSubmit | Enables binding angular expressions to onsubmit events. |
| ngFocus | Specify custom behavior on focus event. |
| ngBlur | Specify custom behavior on blur event. |
| ngCopy | Specify custom behavior on copy event. |
| ngCut | Specify custom behavior on cut event. |
| ngPaste | Specify custom behavior on paste event. |
| ngIf | The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM. |
| ngInclude | Fetches, compiles and includes an external HTML fragment. |
| ngInit | The ngInit directive allows you to evaluate an expression in the current scope. |
| ngList | Text input that converts between a delimited string and an array of strings. The default delimiter is a comma followed by a space - equivalent to ng-list=", ". You can specify a custom delimiter as the value of the ngList attribute - for example, `ng-list=" |
| ngModel | The ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive. |
| ngModelOptions | Allows tuning how model updates are done. Using ngModelOptions you can specify a custom list of events that will trigger a model update and/or a debouncing delay so that the actual update only takes place when a timer expires; this timer will be reset after another change takes place. |
| ngNonBindable | The ngNonBindable directive tells Angular not to compile or bind the contents of the current DOM element. This is useful if the element contains what appears to be Angular directives and bindings but which should be ignored by Angular. This could be the case if you have a site that displays snippets of code, for instance. |
| ngOptions | The ngOptions attribute can be used to dynamically generate a list of <option> elements for the <select> element using the array or object obtained by evaluating the ngOptions comprehension expression. |
| ngPluralize | ngPluralize is a directive that displays messages according to en-US localization rules. These rules are bundled with angular.js, but can be overridden (see Angular i18n dev guide). You configure ngPluralize directive by specifying the mappings between plural categories and the strings to be displayed. |
| ngRepeat | The ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item, and $index is set to the item index or key. |
| ngShow | The ngShow directive shows or hides the given HTML element based on the expression provided to the ngShow attribute. The element is shown or hidden by removing or adding the .ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none (using an !important flag). For CSP mode please add angular-csp.css to your html file (see ngCsp). |
| ngHide | The ngHide directive shows or hides the given HTML element based on the expression provided to the ngHide attribute. The element is shown or hidden by removing or adding the ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none (using an !important flag). For CSP mode please add angular-csp.css to your html file (see ngCsp). |
| ngStyle | The ngStyle directive allows you to set CSS style on an HTML element conditionally. |
| ngSwitch | The ngSwitch directive is used to conditionally swap DOM structure on your template based on a scope expression. Elements within ngSwitch but without ngSwitchWhen or ngSwitchDefault directives will be preserved at the location as specified in the template. |
| ngTransclude | Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion. |
| script | Load the content of a <script> element into $templateCache, so that the template can be used by ngInclude, ngView, or directives. The type of the <script> element must be specified as text/ng-template, and a cache name for the template must be assigned through the element's id, which can then be used as a directive's templateUrl. |
| select | HTML SELECT element with angular data-binding. |
| ngRequired | ngRequired adds the required validator to ngModel. It is most often used for input and select controls, but can also be applied to custom controls. |
| ngPattern | ngPattern adds the pattern validator to ngModel. It is most often used for text-based input controls, but can also be applied to custom text-based controls. |
| ngMaxlength | ngMaxlength adds the maxlength validator to ngModel. It is most often used for text-based input controls, but can also be applied to custom text-based controls. |
| ngMinlength | ngMinlength adds the minlength validator to ngModel. It is most often used for text-based input controls, but can also be applied to custom text-based controls. |
More info can be found here.
In Angular, a Component is a special kind of directive that uses a simpler configuration which is suitable for a component-based application structure.
Advantages of Components:
- simpler configuration than plain directives
- promote sane defaults and best practices
- optimized for component-based architecture
- writing component directives will make it easier to upgrade to Angular 2
When not to use Components:
- for directives that rely on DOM manipulation, adding event listeners etc, because the compile and link functions are unavailable
- when you need advanced directive definition options like priority, terminal, multi-element
- when you want a directive that is triggered by an attribute or CSS class, rather than an element
More info can be found here.
Controllers are the behavior behind the DOM elements. AngularJS lets you express the behavior in a clean readable form without the usual boilerplate of updating the DOM, registering callbacks or watching model changes.
Accomplished using ng-controller
<!doctype html>
<html ng-app="todoApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="second_todo.js"></script>
<style>
.done-true {
text-decoration: line-through;
color: grey;
}
</style>
</head>
<body>
<h2>Todo</h2>
<div ng-controller="TodoListController as todoList">
<span>{{todoList.remaining()}} of {{todoList.todos.length}} remaining</span>
[ <a href="" ng-click="todoList.archive()">archive</a> ]
<ul class="unstyled">
<li ng-repeat="todo in todoList.todos">
<label class="checkbox">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
</label>
</li>
</ul>
<form ng-submit="todoList.addTodo()">
<input type="text" ng-model="todoList.todoText" size="30"
placeholder="add new todo here">
<input class="btn-primary" type="submit" value="add">
</form>
</div>
</body>
</html>
angular.module('todoApp', [])
.controller('TodoListController', function() {
var todoList = this;
todoList.todos = [
{text:'learn angular', done:true},
{text:'build an angular app', done:false}];
todoList.addTodo = function() {
todoList.todos.push({text:todoList.todoText, done:false});
todoList.todoText = '';
};
todoList.remaining = function() {
var count = 0;
angular.forEach(todoList.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};
todoList.archive = function() {
var oldTodos = todoList.todos;
todoList.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.done) todoList.todos.push(todo);
});
};
});
In Angular, a Controller is defined by a JavaScript constructor function that is used to augment the Angular Scope.
When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be created and made available as an injectable parameter to the Controller's constructor function as $scope.
If the controller has been attached using the controller as syntax then the controller instance will be assigned to a property on the new scope.
You can associate Controllers with scope objects implicitly via the ngController directive or $route service.
It is common to attach Controllers at different levels of the DOM hierarchy. Since the ng-controller directive creates a new child scope, we get a hierarchy of scopes that inherit from each other.
More info here.
When the application grows it is a good practice to move view-independent logic from the controller into a service, so it can be reused by other parts of the application as well.
Angular services are: Lazily instantiated – Angular only instantiates a service when an application component depends on it. Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory. Angular offers several useful services (like $http)
To use an Angular service, you add it as a dependency for the component (controller, service, filter or directive) that depends on the service.
A deep link reflects where the user is in the app, this is useful so users can bookmark and email links to locations within apps. Round trip apps get this automatically, but AJAX apps by their nature do not. AngularJS combines the benefits of deep link with desktop app-like behavior.
Starting with AngularJS version 1.2, ngRoute is in its own module and must be loaded by loading the additional angular-route.js file.
More information here
More information here
Client-side form validation is an important part of great user experience. AngularJS lets you declare the validation rules of the form without having to write JavaScript code. Write less code, go have beer sooner.
To allow styling of form as well as controls, ngModel adds these CSS classes:
ng-valid: the model is validng-invalid: the model is invalidng-valid-[key]: for each valid key added by$setValidityng-invalid-[key]: for each invalid key added by$setValidityng-pristine: the control hasn't been interacted with yetng-dirty: the control has been interacted withng-touched: the control has been blurredng-untouched: the control hasn't been blurredng-pending: any$asyncValidatorsare unfulfilled
<div ng-controller="ExampleController">
<form novalidate class="css-form">
Name: <input type="text" ng-model="user.name" required /><br />
E-mail: <input type="email" ng-model="user.email" required /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
<pre>user = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
<style type="text/css">
.css-form input.ng-invalid.ng-touched {
background-color: #FA787E;
}
.css-form input.ng-valid.ng-touched {
background-color: #78FA89;
}
</style>
<script>
angular.module('formExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.master = {};
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
}]);
</script>
Angular provides basic implementation for most common HTML5 input types: (text, number, url, email, date, radio, checkbox), as well as some directives for validation (required, pattern, minlength, maxlength, min, max).
<form name="form" class="css-form" novalidate>
<div>Size (integer 0 - 10):
<input type="number" ng-model="size" name="size" min="0" max="10" integer/>
{{size}}
<br/>
<span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
<span ng-show="form.size.$error.min || form.size.$error.max">The value must be in range 0 to 10!</span>
</div>
<div>Username:
<input type="text" ng-model="name" name="name" username/>
{{name}}
<br/>
<span ng-show="form.name.$pending.username">Checking if this name is available...</span>
<span ng-show="form.name.$error.username">This username is already taken!</span>
</div>
</form>
var app = angular.module('form-example1', []);
var INTEGER_REGEXP = /^-?d+$/;
app.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.integer = function(modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
// consider empty models to be valid
return true;
}
if (INTEGER_REGEXP.test(viewValue)) {
// it is valid
return true;
}
// it is invalid
return false;
};
}
};
});
app.directive('username', function($q, $timeout) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
var usernames = ['Jim', 'John', 'Jill', 'Jackie'];
ctrl.$asyncValidators.username = function(modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
// consider empty model valid
return $q.when();
}
var def = $q.defer();
$timeout(function() {
// Mock a delayed response
if (usernames.indexOf(modelValue) === -1) {
// The username is available
def.resolve();
} else {
def.reject();
}
}, 2000);
return def.promise;
};
}
};
});
More info here.
AngularJS provides built-in services on top of XHR as well as various other backends using third party libraries. Promises further simplify your code by handling asynchronous return of data.
An important part of serious apps is localization. Angular's locale aware filters and stemming directives give you building blocks to make your application available in all locales.