AngularJS Quick Tutorial

AngularJS Quick Tutorial



.

AngularJS Quick Tutorial

This tutorial is taken from toddmotto.com.

Ultimate guide to learning AngularJS in one day

Angular is a client-side MVC/MVVM framework built in JavaScript, essential for modern single page web applications (and even websites). This post is a full end to end crash course from my experiences, advice and best practices I�ve picked up from using it.

Terminology

Angular has an initial short learning curve, you�ll find it�s up and down after mastering the basics. It�s mainly getting to grips with the terminology and �thinking MVC�. MVC stands for Model-View-Controller. Here are the higher level and essential APIs that Angular comes with, and some terminology.

MVC

You�ve probably heard of MVC, used in many programming languages as a means of structuring/architecting applications/software. Here�s a quick breakdown of meanings:
  • Model: the data structure behind a specific piece of the application, usually ported in JSON. Read up on JSON before getting started with Angular as it�s essential for communicating with your server and view. For instance a group of User IDs could have the following model:




{
"users" : [{
"name": "Joe Bloggs",
"id": "82047392"
},{
"name": "John Doe",
"id": "65198013"
}]
}

You�ll then grab this information either from the server via an XHR (XMLHttp Request), in jQuery you�ll know this as the $.ajax _method, and Angular wraps this in _$http, or it�ll be written into your code whilst the page is parsing (from a datastore/database). You can then push updates to your model and send it back.
  • View: The view is simple, it�s your HTML and/or rendered output. Using an MVC framework, you�ll pull down Model data which updates your View and displays the relevant data in your HTML.
  • Controller: Do what they say on the tin, they control things. But what things? Data. Controllers are your direct access from the server to the view, the middle man, so you can update data on the fly via comms with the server and the client.

Setting up an AngularJS project (bare essentials)

First, we need to actually setup the essentials to an Angular project. There are certain things to note before we begin, which generally consist of an ng-app declaration to define your app, a Controller to talk to your view, and some DOM binding and inclusion of Angular. Here are the bare essentials:
Some HTML with ng-* declarations:




<div ng-app="myApp">
<div ng-controller="MainCtrl">
<!-- controller logic -->
</div>
</div>

An Angular Module and Controller:




var myApp = angular.module(myApp, []);

myApp.controller(MainCtrl, [$scope, function ($scope) {
// Controller magic
}]);

Before jumping in, we need to create an Angular module which all our logic will bolt onto. There are many ways to declare modules, and you can chain all of your logic like this (I don�t like this method):




angular.module(myApp, [])
.controller(MainCtrl, [$scope, function ($scope) {...}])
.controller(NavCtrl, [$scope, function ($scope) {...}])
.controller(UserCtrl, [$scope, function ($scope) {...}]);

Setting up a global Module has proved to be the best for Angular projects I�ve worked on. The lack of semi-colons and accidental closing of the �chain� proved counter-productive and frequented unnecessary compiling errors. Go for this:




var myApp = angular.module(myApp, []);
myApp.controller(MainCtrl, [$scope, function ($scope) {...}]);
myApp.controller(NavCtrl, [$scope, function ($scope) {...}]);
myApp.controller(UserCtrl, [$scope, function ($scope) {...}]);

Each new file I create simply grabs the myApp namespace and automatically bolts itself into the application. Yes, I�m creating new files for each Controller, Directive, Factory and everything else (you�ll thank me for this). Concatenate and minify them all and push the single script file into the DOM (using something like Grunt/Gulp).

Controllers

Now you�ve grasped the concept of MVC and a basic setup, let�s check out Angular�s implementation on how you can get going with Controllers.
Taking the example from above, we can take a baby step into pushing some data into the DOM from a controller. Angular uses a templating-style {{ handlebars }} syntax for talking to your HTML. Your HTML should (ideally) contain no physical text or hard coded values to make the most of Angular. Here�s an example of pushing a simple String into the DOM:




<div ng-app="myApp">
<div ng-controller="MainCtrl">
{{ text }}
</div>
</div>
var myApp = angular.module(myApp, []);

myApp.controller(MainCtrl, [$scope, function ($scope) {

$scope.text = Hello, Angular fanatic.;

}]);

And the live output:
The key rule concept here is the $scope concept, which you�ll tie to all your functions inside a specific controller. The $scope refers to the current element/area in the DOM (no, not the same as this), and encapsulates a very clever scoping capability that keeps data and logic completely scoped inside elements. It brings JavaScript public/private scoping to the DOM, which is fantastic.
The $scope concept may seem scary at first, but it�s your way into the DOM from the server (and static data if you have that too)! The demo gives you a basic idea of how you can �push� data to the DOM.
Let�s look at a more representative data structure that we�ve hypothetically retrieved from the server to display a user�s login details. For now I�ll use static data; I�ll show you how to fetch dynamic JSON data later.
First we�ll setup the JavaScript:




var myApp = angular.module(myApp, []);

myApp.controller(UserCtrl, [$scope, function ($scope) {

// Lets namespace the user details
// Also great for DOM visual aids too
$scope.user = {};
$scope.user.details = {
"username": "Todd Motto",
"id": "89101112"
};

}]);

Then port it over to DOM to display this data:




<div ng-app="myApp">
<div ng-controller="UserCtrl">
<p class="username">Welcome, {{ user.details.username }}</p>
<p class="id">User ID: {{ user.details.id }}</p>
</div>
</div>

Output:
It�s important to remember that Controllers are for data only, and creating functions (event functions too!) that talk to the server and push/pull JSON data. No DOM manipulation should be done here, so put your jQuery toolkit away. Directives are for DOM manipulation, and that�s up next.
Protip: throughout the Angular documentation (at the time of writing this) their examples show this usage to create Controllers:




var myApp = angular.module(myApp, []);

function MainCtrl ($scope) {
//...
};

� DON�T do this. This exposes all your functions to the global scope and doesn�t keep them tied in very well with your app. This also means that you can�t minify your code or run tests very easily. Don�t pollute the global namespace and keep your controllers inside your app.

Directives

A directive (checkout my post on Directives from existing scripts/plugins) in its simplest form is a small piece of templated HTML, preferably used multiple times throughout an application where needed. It�s an easy way to inject DOM into your application with no effort at all, or perform custom DOM interactions. Directives are not simple at all; there is an incredible learning curve to fully conquering them, but this next phase will let you hit the ground running.
So what are directives useful for? A lot of things, including DOM components, for example tabs or navigation elements - really depends on what your app makes use of in the UI. Let me put it this way, if you�ve toyed with ng-show or ng-hide, those are directives (though they don�t inject DOM).
For this exercise, I�m going to keep it really simple and create a custom type of button (called customButton) that injects some markup that I hate to keep typing out. There are various ways to define Directives in the DOM, these could look like so:




<!-- 1: as an attribute declaration -->
<a custom-button>Click me</a>

<!-- 2: as a custom element -->
<custom-button>Click me</custom-button>

<!-- 3: as a class (used for old IE compat) -->
<a class="custom-button">Click me</a>

<!-- 4: as a comment (not good for this demo, however) -->
<!-- directive: custom-button -->

I prefer using them as an attribute, custom elements are coming in the future of HTML5 under the Web Components, but Angular report these quite buggy in some older browsers.
Now you know how to declare where Directives are used/injected, let�s create this custom button. Again, I�ll hook into my global namespace myApp for the application, this is a directive in its simplest form:




myApp.directive(customButton, function () {
return {
link: function (scope, element, attrs) {
// DOM manipulation/events here!
}
};
});

I define my directive using the .directive() method, and pass in the directive�s name �customButton�. When you capitalise a letter in a Directive�s name, its use case is then split via a hyphen in the DOM (as above).
A directive simply returns itself via an Object and takes a number of parameters. The most important for me to master first are, restrict, replace, transclude, template and templateUrl, and of course the link property. Let�s add those others in:




myApp.directive(customButton, function () {
return {
restrict: A,
replace: true,
transclude: true,
template: <a href="" class="myawesomebutton" ng-transclude> +
<i class="icon-ok-sign"></i> +
</a>,
link: function (scope, element, attrs) {
// DOM manipulation/events here!
}
};
});

Output:
Make sure you Inspect Element to see the additional markup injected. Yes, I know, there is no icon included as I never included Font Awesome, but you see how it works. Now for the Directive properties explanations:
  • restrict: This goes back to usage, how do we restrict the element�s usage? If you�re using a project that needs legacy IE support, you�ll probably need attribute/class declarations. Restricting as �A� means you restrict it as an Attribute. �E� for Element, �C� for Class and �M� for Comment. These have a default as �EA�. Yes, you can restrict to multiple use cases.
  • replace: This replaces the markup in the DOM that defines the directive, used in the example, you�ll notice how initial DOM is replaced with the Directive�s template.
  • transclude: Put simply, using transclude allows for existing DOM content to be copied into the directive. You�ll see the words �Click me� have �moved� into the Directive once rendered.
  • template: A template (as above) allows you to declare markup to be injected. It�s a good idea to use this for tiny pieces of HTML only. Injected templates are all compiled through Angular, which means you can declare the handlebar template tags in them too for binding.
  • templateUrl: Similar to a template, but kept in its own file or <script> tag. You can do this to specify a template URL, which you�ll want to use for manageable chunks of HTML that require being kept in their own file, just specify the path and filename, preferably kept inside their own templates directory:




myApp.directive(customButton, function () {
return {
templateUrl: templates/customButton.html
// directive stuff...
};
});

And inside your file (filename isn�t sensitive at all):




<!-- inside customButton.html -->
<a href="" class="myawesomebutton" ng-transclude>
<i class="icon-ok-sign"></i>
</a>

What�s really good about doing this, is the browser will actually cache the HTML file, bravo! The other alternative which isn�t cached is declaring a template inside <script> tags:




<script type="text/ng-template" id="customButton.html">
<a href="" class="myawesomebutton" ng-transclude>
<i class="icon-ok-sign"></i>
</a>
</script>

You�ll tell Angular that it�s an ng-template and give it the ID. Angular will look for the ng-template or the *.html file, so whichever you prefer using. I prefer creating *.html files as they�re very easy to manage, boost performance and keep the DOM very clean, you could end up with 1 or 100 directives, you want to be able to navigate through them easily.

Services

Services are often a confusing point. From experience and research, they�re more a stylistic design pattern rather than providing much functional difference. After digging into the Angular source, they look to run through the same compiler and they share a lot of functionality. From my research, you should use Services for singletons, and Factories for more complex functions such as Object Literals and more complicated use cases.
Here�s an example Service that multiples two numbers:




myApp.service(Math, function () {
this.multiply = function (x, y) {
return x * y;
};
});

You would then use this inside a Controller like so:




myApp.controller(MainCtrl, [$scope, function ($scope) {
var a = 12;
var b = 24;

// outputs 288
var result = Math.multiply(a, b);
}]);

Yes, multiplication is very easy and doesn�t need a Service, but you get the gist.
When you create a Service (or Factory) you�ll need to use dependency injection to tell Angular it needs to grab hold of your new Service - otherwise you�ll get a compile error and your Controller will break. You may have noticed the function ($scope) part inside the Controller declaration by now, and this is simple dependency injection. Feed it the code! You�ll also notice [�$scope�] before the function ($scope) too, I�ll come onto this later. Here�s how to use dependency injection to tell Angular you need your service:




// Pass in Math
myApp.controller(MainCtrl, [$scope, Math, function ($scope, Math) {
var a = 12;
var b = 24;

// outputs 288
var result = Math.multiply(a, b);
}]);

Factories

Coming from Services to Factories should be simple now, we could create an Object Literal inside a Factory or simply provide some more in-depth methods:




myApp.factory(Server, [$http, function ($http) {
return {
get: function(url) {
return $http.getlink download