Author Archives: admin

Angular JS: Javascript promises

[Fuente:  http://wildermuth.com/2013/8/3/JavaScript_Promises]

En este artículo hablamos sobre el concepto de objecto promise que varias librerias Javascript utilizan (incluyendo AngularJS , jQuery , Dojo y WinJS).

Una promise es un patrón para manejar operaciones asíncronas. El problema es que esencialmente cuando comienzas una operación asíncrona, necesitas ejecutar cierto código cuando la operación se ha completado. El código asíncrono se ha hecho tan común que la mayoría de las librerias javascript han creado una solución pasar los callbacks Pero hay ciertas semejanzas en cómo lo hacen todas. Veamos jQuery como ejemplo:

var $info = $("#info");

$.ajax({
    url:"/echo/json/",
    data: { json: JSON.stringify({"name": "someValue"}) },
    type:"POST",
    success: function(response)
    {
       $info.text(response.name);
    }
});

En este ejemplo puedes ver que jQuery utiliza la propiedad “success” de los settings para especificar el callback. Esto no es un promise aunque sí es una forma de pasar funciones callback. When the ajax call is complete, it calls the success function. Depending on the library that uses asynchronous operations, you might pass in a set of callbacks (e.g. for success or failure). There are a ton of ways to accomplish this.

El patrón promise intenta simplificar este proceso. La operación asíncrona simplemente retorna un objeto llamado una promise.Este objeto promise te permite invocar un método llamado “then” que te permite especificar las funciones a utilizar como callbacks. Veamos como consumir una promise utilizando jQuery como ejemplo:

var $info = $("#info");

$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
});

Lo que es interesante aquí , es que el objeto que ajax retorna es el objeto xhr que implementa el patrón promise de forma que podemos invocar then como se ha mostrado. El poder de invocar a then es que puedes encadenar varias operaciones y completar la operación invocando “done” como mostramos en el siguiente ejemplo:

var $info = $("#info");

$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
})
.then(function () {
    $info.append("...More");
})
.done(function () {
    $info.append("...finally!");
});

Because many libraries are starting to take on the promise pattern, handling asynchronous operations should be easier no matter what code you’re writing (e.g. NodeJS, in-browser JS, etc.). But what does a promise look like from the other side?

One important key to the pattern is that the then function can accept two functions. The first is for the success callback; the second for the failure callback like so:

var $info = $("#info");

$.ajax({
    // Change URL to see error happen
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    // success
    $info.text(response.name);
}, 
function () {
    // failure
    $info.text("bad things happen to good developers");
})
.always(function () {
    $info.append("...finally");
});

Notice that in jQuery we’re using a call to always to specify that we want to be called whether the success or failure was called.

Let’s see how using a promise looks. Here is an example from AngularJS:

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

m.factory("dataService", function ($q) {
    function _callMe() {
        var d = $q.defer();

        setTimeout(function () {
            d.resolve();
            //defer.reject();
        }, 100);

        return d.promise;
    }

    return {
        callMe: _callMe
    };
});

function myCtrl($scope, dataService) {
    $scope.name = "None";
    $scope.isBusy = true;
    dataService.callMe()
      .then(function () {
        // Successful
        $scope.name = "success";
      }, 
      function () {
        // failure
        $scope.name = "failure";
      })
      .then(function () {
        // Like a Finally Clause
        $scope.isBusy = false;
      });
}

AngularJS uses an implementation (see the $q variable) that is started with a call to defer() This returns an object that contains ways to mark a successful or failure condition as well as the promise itself. Notice that in the _callMe function the variable is created by calling $q.defer() then the d.promise is returned from the function so that the caller can call the promise methods (e.g. then). When the actual asynchronous operation is performed (in this case mocked up as a setTimeout call), we can use the resolve method on the defer’d object to tell the promise that we completed successfully (and therefore call the first function in the then method below). If we were to call reject, the second method (the failure call) would be called instead.

You can play with these examples in JSFiddle and see what you can make happen. Promises are a really simple and cool way to handle asynchronicity. What I really like about it is that it simplifies your code (so that you don’t have the triangle of doom when you have to nest callback functions inside each other. This makes it easy.

AngularJs: Single Page Apps with AngularJS Routing and Templating

[Fuente: http://scotch.io/tutorials/javascript/single-page-apps-with-angularjs-routing-and-templating]

Overview

Single page apps are becoming increasingly popular. Sites that mimic the single page app behavior are able to provide the feel of a phone/tablet application. Angular helps to create applications like this easily.

Our Simple App

We’re just going to make a simple site with a home, about, and contact page. Angular is built for much more advanced applications than this, but this tutorial will show many of the concepts needed for those larger projects.

Goals

  • Single page application
  • No page refresh on page change
  • Different data on each page
 While this can be done with just Javascript and AJAX calls, Angular will make this process easier as our app starts growing.

File Structure

- script.js 		<!-- stores all our angular code -->
	- index.html 	<!-- main layout -->
	- pages 	<!-- the pages that will be injected into the main layout -->
			----- home.html
			----- about.html
			----- contact.html

HTML

This is the simple part. We’re using Bootstrap and Font Awesome. Open up your index.html file and we’ll add a simple layout with a navigation bar.

<!-- index.html -->
	<!DOCTYPE html>
	<html>
	<head>
	  <!-- SCROLLS -->
	  <!-- load bootstrap and fontawesome via CDN -->
	  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
	  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />

	  <!-- SPELLS -->
	  <!-- load jquery, bootstrap, and angular via CDN -->
	  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
	  <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
	  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
	  <script src="script.js"></script>
	</head>
	<body>

		<!-- HEADER AND NAVBAR -->
		<header>
			<nav class="navbar navbar-default">
			<div class="container">
				<div class="navbar-header">
					<a class="navbar-brand" href="/">Angular Routing Example</a>
				</div>

				<ul class="nav navbar-nav navbar-right">
					<li><a href="#"><i class="fa fa-home"></i> Home</a></li>
					<li><a href="#about"><i class="fa fa-shield"></i> About</a></li>
					<li><a href="#contact"><i class="fa fa-comment"></i> Contact</a></li>
				</ul>
			</div>
			</nav>
		</header>

		<!-- MAIN CONTENT AND INJECTED VIEWS -->
		<div id="main">

			<!-- angular templating -->
			<!-- this is where content will be injected -->

		</div>

		<!-- FOOTER -->
		<footer class="text-center">
			View the tutorial on <a href="http://scotch.io/tutorials/angular-routing-and-templating-tutorial">Scotch.io</a>
		</footer>

	</body>
	</html>

For linking to pages, we’ll use the #. We don’t want the browser to think we are actually travelling to about.html or contact.html.

Angular Application

Module and Controller

We’re going to setup our application. Let’s create the angular module and controller. Check out the docs for more information on each.

First, we have to create our module and controller in javascript. We will do that now in script.js.

// script.js

	// create the module and name it scotchApp
	var scotchApp = angular.module('scotchApp', []);

	// create the controller and inject Angular's $scope
	scotchApp.controller('mainController', function($scope) {

		// create a message to display in our view
		$scope.message = 'Everyone come and see how good I look!';
	});

Let’s add the module and controller to our HTML so that Angular knows how to bootstrap our application. To test that everything is working, we will also show the $scope.message variable that we created.

<!-- index.html -->
	<!DOCTYPE html>

	<!-- define angular app -->
	<html ng-app="scotchApp">
	<head>
	  <!-- SCROLLS -->
	  <!-- load bootstrap and fontawesome via CDN -->
	  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
	  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />

	  <!-- SPELLS -->
	  <!-- load jquery, bootstrap, and angular via CDN -->
	  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
	  <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
	  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
          <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>
	  <script src="script.js"></script>
	</head>

	<!-- define angular controller -->
	<body ng-controller="mainController">

	...

	<!-- MAIN CONTENT AND INJECTED VIEWS -->
	<div id="main">
		{{ message }}

		<!-- angular templating -->
		<!-- this is where content will be injected -->
	</div>

Inside of our main div, we will now see the message that we created. Since we have our module and controller set up and we know that Angular is working properly, we will start working on using this layout to show the different pages.

Injecting Pages into the Main Layout

ng-view is an Angular directive that will include the template of the current route (/home, /about, or /contact) in the main layout file. In plain words, it takes the file we want based on the route and injects it into our main layout (index.html).

We will add the ng-view code to our site in the div#main to tell Angular where to place our rendered pages.

<!-- index.html -->
	...

	<!-- MAIN CONTENT AND INJECTED VIEWS -->
	<div id="main">

		<!-- angular templating -->
		<!-- this is where content will be injected -->
		<div ng-view></div>

	</div>

	...

Configure Routes and Views

Since we are making a single page application and we don’t want any page refreshes, we’ll use Angular’s routing capabilities.

Let’s look in our Angular file and add to our application. We will be using $routeProvider in Angular to handle our routing. This way, Angular will handle all of the magic required to go get a new file and inject it into our layout.

AngularJS 1.2 and Routing The ngRoute module is no longer included in Angular after version 1.1.6. You will need to call the module and add it to the head of your document to use it. This tutorial has been updated for AngularJS 1.2

// script.js

	// create the module and name it scotchApp
        // also include ngRoute for all our routing needs
	var scotchApp = angular.module('scotchApp', ['ngRoute']);

	// configure our routes
	scotchApp.config(function($routeProvider) {
		$routeProvider

			// route for the home page
			.when('/', {
				templateUrl : 'pages/home.html',
				controller  : 'mainController'
			})

			// route for the about page
			.when('/about', {
				templateUrl : 'pages/about.html',
				controller  : 'aboutController'
			})

			// route for the contact page
			.when('/contact', {
				templateUrl : 'pages/contact.html',
				controller  : 'contactController'
			});
	});

	// create the controller and inject Angular's $scope
	scotchApp.controller('mainController', function($scope) {
		// create a message to display in our view
		$scope.message = 'Everyone come and see how good I look!';
	});

	scotchApp.controller('aboutController', function($scope) {
		$scope.message = 'Look! I am an about page.';
	});

	scotchApp.controller('contactController', function($scope) {
		$scope.message = 'Contact us! JK. This is just a demo.';
	});

Now we have defined our routes with $routeProvider. As you can see by the configuration, you can specify the route, the template file to use, and even a controller. This way, each part of our application will use its own view and Angular controller.

Our home page will pull the home.html file. About and contact will pull their respective files. Now if we view our app, and click through the navigation, our content will change just how we wanted.

To finish off this tutorial, we just need to define the pages that will be injected. We will also have them each display a message from its respectiive controller.

<!-- home.html -->
	<div class="jumbotron text-center">
		<h1>Home Page</h1>

		<p>{{ message }}</p>
	</div>


<!-- about.html -->
	<div class="jumbotron text-center">
		<h1>About Page</h1>

		<p>{{ message }}</p>
	</div>


<!-- contact.html -->
	<div class="jumbotron text-center">
		<h1>Contact Page</h1>

		<p>{{ message }}</p>
	</div>

SEO on Single Page Apps

Ideally, this technique would be used for an application after a person has signed in. You wouldn’t really want those pages indexed since they are personalized to that specific user. For example, you wouldn’t want your Reader account, Facebook logged in pages, or Blog CMS pages indexed.

If you did want SEO for you application though, how does SEO work for applications/sites that get their pages built with Javascript? Search enginges have a difficult time processing these applications because the content is built dynamically by the browser and not visible to crawlers.

Making Your App SEO Friendly

Techniques to make Javascript single page applications SEO friendly require regular maintenance. According to the officialGoogle suggestions, you would create HTML snapshots. The basic overview of how it would work is that:

  1. A crawler would find a pretty URL (http://scotch.io/seofriendly#key=value)
  2. The crawler would then ask the server for the contents of this URL (in a special modified way)
  3. Web server returns content using an HTML snapshot
  4. HTML snapshot is processed by the crawler
  5. Search results then show the original URL

For more information on this process, be sure to look at Google’s AJAX Crawling and their guide on creating HTML snapshots.

Conclusion

This was a very simple tutorial on how to get Angular routing to work with a layout and separate views. Now you can go ahead and create larger single page applications. There is much more to learn with Angular and I’ll keep writing about different features along my learning journey of Angular.

If anyone has any suggestions for future Angular articles or different ways to do what we’ve just done here (there are so many ways to write the same thing, it can drive a person insane), sound off in the comments.

Angular JS: UI-bootstrap

Getting started

Dependencies

This repository contains a set of native AngularJS directives based on Bootstrap’s markup and CSS. As a result no dependency on jQuery or Bootstrap’s JavaScript is required. The only required dependencies are:

  • AngularJS (minimal version 1.0.8)
  • Bootstrap CSS (tested with version 3.0.3). This version of the library (0.10.0) works only with Bootstrap CSS in version 3.x. 0.8.0 is the last version of this library that supports Bootstrap CSS in version 2.3.x.

Files to download

Build files for all directives are distributed in several flavours: minified for production usage, un-minified for development, with or without templates. All the options are described and can be downloaded from here.

Alternativelly, if you are only interested in a subset of directives, you can create your own build.

Whichever method you choose the good news that the overall size of a download is very small: <20kB for all directives (~5kB with gzip compression!)

Installation

As soon as you’ve got all the files downloaded and included in your page you just need to declare a dependency on the ui.bootstrap module:

angular.module('myModule', ['ui.bootstrap']);

You can fork one of the plunkers from this page to see a working example of what is described here.

CSS

Original Bootstrap’s CSS depends on empty href attributes to style cursors for several components (pagination, tabs etc.). But in AngularJS adding empty href attributes to link tags will cause unwanted route changes. This is why we need to remove empty href attributes from directive templates and as a result styling is not applied correctly. The remedy is simple, just add the following styling to your application:

.nav, .pagination, .carousel, .panel-title a { cursor: pointer; }

AngularJs: Kickstart Your AngularJS Development with Yeoman, Grunt and Bower

[Fuente: http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/]

Whether you love or hate it, there’s no denying that AngularJS is the framework on every developer’s lips. It may not be for everybody, but AngularJS has a quirky, efficient and powerful feature set. Couple that with a few useful development tools like Yeoman, Grunt and Bower and you’ve got yourself an incredibly fast rapid prototyping process.

What we’ll cover

This AngularJS tutorial will cover:

  • Generating a bare bones AngularJS app with Yeoman
  • Using Grunt to speed up development and help perform repetitive tasks
  • Using Bower to add third party plugins/frameworks
  • Making minor changes to your AngularJS app

Prerequisites

To get the most out of this tutorial we recommend you have the following skills and resources available:

  • A terminal and basic knowledge of the command line
  • NodeJS and NPM installed
  • Fundamental JS, CSS and HTML knowledge

Files

You can find a repo of this tutorial project here.

Let’s get started yo!

Alright, let’s get this thing underway. The first thing you need to do is install Yeoman, Grunt and Bower. We’re going to use the Node Package Manager to do this all at once. In a terminal, run the following:

npm install -g yo grunt-cli bower

As simply as that, we now have a powerful set of tools at our disposal. I’ll explain each one as we use it.

Yeoman

Yeoman is used to generate the scaffolding of your app for you. It’ll create the basic folders, files and configurations to get you up and running quickly. Not only that but there are some great custom generators available to create apps of a particular kind – we’re going to use the nifty AngularJS generator.

One of the best features of Yeoman is the ability to use custom generators. We’re going to intall the AngularJS generator to help us get up and running with Angular as quick as possible.

Run the following to install the AngularJS generator:

npm install -g generator-angular

Now it’s time to generate a shiny new AngularJS application. In a fresh project directory, run:

yo angular <your_app_name>

The generator will ask you a couple of questions. You can answer yes to include Twitter’s bootstrap. Also answer yes to include ngResource. The rest we won’t need for now so answer no.

Sit back (for a few seconds) and watch the generator do its magic. Yeoman will create your files and folders, then it will run bower install (more on this in a moment) and npm install to fetch any dependencies and lastly it’ll perform any mandatory configuration.

What’s in the box?

Let’s take a look at what Yeoman’s given us:

  • .bowerrc
  • .editorconfig
  • .gitattributes
  • .gitignore
  • .jshintrc
  • Gruntfile.js
  • app/
  • component.json
  • karma-e2e.conf.js
  • karma.conf.js
  • node_modules/
  • package.json
  • test/

Let’s go over some of the more important things to notice here:

app/ directory
The app directory contains your static app. It has your html, css and javascript in it and it’s where you’ll spend most of your time developing.

package.json
The package.json file helps npm to identify our project as well as to manage all of it’s dependencies. It can also contain all sorts of other metadata relevant to your project.

node_modules
This one is self explanatory. This is where all the node modules that your project depends on are stored.

Gruntfile.js
The Gruntfile is a javascript file that is responsible for configuring your project as well as any tasks or plugins that your project requires. For instance, your gruntfile might specify that your project uses Uglify and that you want it to run uglify on a particular directory at build time. More about Grunt in a moment.

component.json
The component.json file is used to inform the Bower package manager of your projects dependencies as well as other metadata. In recent versions of Bower this file is called bower.json – more on that in a moment.

.bowerrc
The .bowerrc file is used to pass general config options to bower.

Karma files
Karma is a testing framework. We’ll use it to run a few tests for our Angular app.

Phew! That’s quite a lot to take in – once you get more familiar with the output of a yeoman generator however, you’ll learn to love the fact that it handles all of this for you!

Let’s add a few more things to our project before we start get on to some actual development.

Bower – A package manager for the web

Before we use Bower, there’s a small bit of config we have to do ourselves. Bower recently changed their naming convention of component.json files to bower.json files so we need to bring our code base in line with that.

The first thing we need to do is make a small change to our Bower config in .bowerrc so open it up and add the following line:

  {
      "directory": "app/components",
      "json": "bower.json" // Add this line
  }

What this does, is it tells Bower to use a package’s bower.json file for instructions on how to install that package.

Since we’re using bower for our own project’s dependencies, we’ll need to rename the component.json file in our project root to bower.json as well. A small ask when using such cutting edge technologies 🙂

Bower 

Bower is a package manager. It will help us to quickly find and install our favourite CSS frameworks, javascript libraries and plugins with just a few simple commands.

Ok, let’s give Bower a whirl. Yeoman kindly used bower to install Bootstrap for us earlier, but that was just the Bootstrap CSS. We want all the nifty Javascript widgets as well.

Since we’re building an AngularJS app, we’ll need Bootstrap javascript that works with Angular.

Luckily, the team over at Angular UI have ported all the Bootstrap Javascript into Angular!. Let’s use Bower to install their library.

bower install angular-bootstrap --save

The –save flag tells bower to add this to our bower.json file as a dependency

Fantastic! That was easy wasn’t it? Now, navigate into your app/ directory and let’s see what we’ve got to work with.

Our static app

Take a look at the contents of the app/ directory.

  • favicon.ico
  • index.html
  • robots.txt
  • components/
  • scripts/
  • styles/
  • views/

index.html
This should be familiar to most of you, this is the core html page of your app.

components/ directory
The components directory is like the node_modules directory but for Bower. It’s where all the packages you install with Bower will be kept. AngularUI Bootstrap, for instance, will be in there.

scripts/ directory
Again, familiar territory to most. This is where your apps javascript is stored. Note that libraries such as AngularJS will exist in the components directory, so scripts/ is for your files that you write!

styles/ directory
All your css/sass to make your app look moar pretty.

Views
This nifty folder is where your Angular Templates will reside.

Next up we’ll take a closer look at the AngularJS files

AngularJS

The Yeoman Angular generator has given us the bare essentials: A module, a controller and a view. Let’s take a look at each of those:

The Module: /app/scripts/app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'use strict';
// Here we set up an angular module. We'll attach controllers and
// other components to this module.
angular.module('testApp', [])
  // Angular supports chaining, so here we chain the config function onto
  // the module we're configuring.
  .config(function ($routeProvider) {
    // We use AngularJS dependency injection to fetch the route provider.
    // The route provider is used to setup our app's routes.
    // The config below simply says when you visit '/' it'll render
    // the views/main.html template controlled by the MainCtrl controller.
    // The otherwise method specifies what the app should do if it doesn't recognise
    // the route entered by a user. In this case, redirect to home.
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

The Controller: /app/scripts/controllers/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'use strict';
  // Here we attach this controller to our testApp module
  angular.module('testApp')
 
    // The controller function let's us give our controller a name: MainCtrl
    // We'll then pass an anonymous function to serve as the controller itself.
    .controller('MainCtrl', function ($scope) {
 
      // Using AngularJS dependency injection, we've injected the $scope variable
      // Anything we attach to scope will be available to us in the view.
 
      // In this case, we're attaching a collection of Awesome Things to display
      // in app/views/main.html
      $scope.awesomeThings = [
        'HTML5 Boilerplate',
        'AngularJS',
        'Karma'
      ];
    });

The View: app/views/main.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  <div class="hero-unit">
    <h1>'Allo, 'Allo!</h1>
    <p>You now have</p>
    <ul>
 
        <!-- Here we use the AngularJS directive: ng-repeat to loop through our awesomeThings
        and print them out as list items using the {{}} bindings -->
        <li ng-repeat="thing in awesomeThings">{{thing}}</li>
    </ul>
    <p>installed.</p>
    <h3>Enjoy coding! - Yeoman</h3>
  </div>
[/js]
 
<strong>The Index File: app/index.html</strong>
1  <!doctype html>
  <html>
    <head>...</head>
    <!-- The ng-app directive tells angular which module we'll use
    for our app. In this case the one defined in scripts/app.js -->
    <body ng-app="testApp">
      ...
      <!-- The ng-view directive specifies that our templates
      (such as views/main.html) will be loaded into this div. -->
      <div class="container" ng-view></div>
 
      <!-- Here we load AngularJS and the AngularJS resource component -->
      <script src="components/angular/angular.js"></script>
      <script src="components/angular-resource/angular-resource.js"></script>
 
      <!-- Here we include our own angular scripts -->
      <!-- build:js scripts/scripts.js -->
      <script src="scripts/app.js"></script>
      <script src="scripts/controllers/main.js"></script>
      <!-- endbuild -->
 
      ...
    </body>
  </html>

Let’s see it in action!

We’re ready to take our first look at our application. Navigate back to the root directory of your app and run:

grunt server

Grunt 
Grunt is a powerful, feature rich task runner for Javascript. In brief, it lets you automate repetitive tasks like compiling coffeescript, minifying css, code validation etc. We’ll be using it to do all of that as well as prepare our code for development and deployment.

Grunt is going to whip through our project folder and prepare everything for us such as compiling our included Bootstrap SASS down to css.

After a few seconds a browser window should pop up with your app running and looking all fancy.

Just to be sure, view the source of the page and take a look at the main.css file that’s included. It should be full of Bootstrap code – thanks to the magic of Bower and Grunt.

Let’s change it up

It’s about time to try our hand at making some changes. Since this is Angular, we’ll start with some AngularJS Testing.

Yeoman was kind enough to generate an example test for our controller, so let’s start there.

We’re going to add another thing to our list of awesome things so open test/spec/controllers/main.js and let’s change our test to expect 4 awesome things instead of 3:

test/spec/controllers/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
'use strict';
describe('Controller: MainCtrl', function () {
  // load the controller's module
  beforeEach(module('testApp'));
  var MainCtrl,
    scope;
  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    MainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));
  it('should attach a list of awesomeThings to the scope', function () {
    // Change this line
    expect(scope.awesomeThings.length).toBe(3);
    // To this
    expect(scope.awesomeThings.length).toBe(4);
  });
});

Now we can use another great feature of Grunt:

grunt test

This will run our Karma tests. They should fail because the test expects 4 awesomeThings and we still only have 3. Let’s go fix that to make our tests pass.

Open app/scripts/controllers/main.js and add another awesome thing to the list:

/app/scripts/controllers/main.js

1
2
3
4
5
6
7
8
.controller('MainCtrl', function ($scope) {
  $scope.awesomeThings = [
    'HTML5 Boilerplate',
    'AngularJS',
    'Karma',
    'SitePoint'
  ];
});

Save the file and run the tests again:

grunt test

This time they should pass. Now you can fire up the app in your browser (grunt server) and notice that there’s an additional bullet point. Neat huh?

Using our Bower included package

Let’s use the AngularUI Bootstrap library that we included earlier to turn our list of awesomeThings into a dropdown of awesomeThings.

Important Since Bower is just a package manager, it’s not responsible for adding our files to our index.html file. We need to do that ourselves.

So open up app/index.html and add the following line:

1
<script src="components/angular-bootstrap/ui-bootstrap.js"></script>

Then, as per the Getting Started documentation on AngularUI Bootstrap’s site, we need to add their module as a dependency to our own Angular module

Open app/scripts/app.js and add the ui.bootstrap module as a dependency:

/app/scripts/app.js

1
2
3
4
'use strict';
angular.module('testApp', ['ui.bootstrap'])
...

Alright it’s ready to use. Now we need to make a few changes to our view:

The View: app/views/main.html

1
2
3
4
5
6
7
8
9
10
11
12
<ul>
  <li class="dropdown">
    <a class="dropdown-toggle">
      Click me to see some awesome things!
    </a>
    <ul class="dropdown-menu">
      <li ng-repeat="thing in awesomeThings">
        <a>{{thing}}</a>
      </li>
    </ul>
  </li>
</ul>

We’ve used some bootstrap css classes, and moved our ng-repeat to create menu items instead of just a plain old list.

AngularUI Bootstrap directives work as css classes, so simply by adding the dropdown-toggle class to our tag we’ll have a fully functioning dropdown!

We will need to add the Bootstrap UI module to our tests otherwise they’ll fail so make the following changes:

test/spec/controllers/main.js

1
2
3
4
5
6
7
8
9
10
'use strict';
describe('Controller: MainCtrl', function () {
  // load the controller's module
  beforeEach(module('testApp'));
  // load the BootstrapUI module
  beforeEach(module('ui.bootstrap')); // Add this line
 ...
});

/karma.conf.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Karma configuration
// base path, that will be used to resolve files and exclude
basePath = '';
// list of files / patterns to load in the browser
files = [
  JASMINE,
  JASMINE_ADAPTER,
  'app/components/angular/angular.js',
  'app/components/angular-mocks/angular-mocks.js',
  'app/components/angular-bootstrap/ui-bootstrap.js', // Add this line
  'app/scripts/*.js',
  ...

Run grunt test to make sure everything passes

Now you can open up your app in the browser (grunt server) once more and take a look at your handy work.

Conclusion

Well there you have it! A simple Angular App, a third party JS library, some tests, minification and a whole heap of other goodies with minimal effort!

We’ve only scratched the surface of what’s possible with Yeoman and its fellows – but I hope this will inspire you to whip up a quick AngularJS app the next time you have a great idea!

Look out for more AngularJS tutorials and articles on AngularJS best practices coming soon!

Comments on this article are closed. Have a question about AngularJS? Why not ask it on our forums?

AngularJS: Unit Testing

JavaScript is a dynamically typed language which comes with great power of expression, but it also comes with almost no help from the compiler. For this reason we feel very strongly that any code written in JavaScript needs to come with a strong set of tests. We have built many features into Angular which makes testing your Angular applications easy. So there is no excuse for not testing.

It is all about NOT mixing concerns

Unit testing as the name implies is about testing individual units of code. Unit tests try to answer questions such as “Did I think about the logic correctly?” or “Does the sort function order the list in the right order?”

In order to answer such a question it is very important that we can isolate the unit of code under test. That is because when we are testing the sort function we don’t want to be forced into creating related pieces such as the DOM elements, or making any XHR calls in getting the data to sort.

While this may seem obvious it can be very difficult to call an individual function on a typical project. The reason is that the developers often mix concerns resulting in a piece of code which does everything. It makes an XHR request, it sorts the response data and then it manipulates the DOM.

With Angular we try to make it easy for you to do the right thing, and so we provide dependency injection for your XHR (which you can mock out) and we created abstractions which allow you to sort your model without having to resort to manipulating the DOM. So that in the end, it is easy to write a sort function which sorts some data, so that your test can create a data set, apply the function, and assert that the resulting model is in the correct order. The test does not have to wait for the XHR response to arrive, create the right kind of test DOM, nor assert that your function has mutated the DOM in the right way.

With great power comes great responsibility

Angular is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but Angular is not magic. If you don’t follow these guidelines you may very well end up with an untestable application.

Dependency Injection

There are several ways in which you can get a hold of a dependency. You can: 1. Create it using the new operator. 2. Look for it in a well-known place, also known as a global singleton. 3. Ask a registry (also known as service registry) for it. (But how do you get a hold of the registry? Most likely by looking it up in a well known place. See #2.) 4. Expect it to be handed to you.

Out of the four options in the list above, only the last one is testable. Let’s look at why:

Using the new operator

While there is nothing wrong with the new operator fundamentally, a problem arises when calling new on a constructor. This permanently binds the call site to the type. For example, lets say that we try to instantiate an XHR that will retrieve data from the server.

function MyClass() {
  this.doWork = function() {
    var xhr = new XHR();
    xhr.open(method, url, true);
    xhr.onreadystatechange = function() {...}
    xhr.send();
  }
}

A problem surfaces in tests when we would like to instantiate a MockXHR that would allow us to return fake data and simulate network failures. By calling new XHR() we are permanently bound to the actual XHR and there is no way to replace it. Yes, we could monkey patch, but that is a bad idea for many reasons which are outside the scope of this document.

Here’s an example of how the class above becomes hard to test when resorting to monkey patching:

var oldXHR = XHR;
XHR = function MockXHR() {};
var myClass = new MyClass();
myClass.doWork();
// assert that MockXHR got called with the right arguments
XHR = oldXHR; // if you forget this bad things will happen

Global look-up:

Another way to approach the problem is to look for the service in a well-known location.

function MyClass() {
  this.doWork = function() {
    global.xhr({
      method:'...',
      url:'...',
      complete:function(response){ ... }
    })
  }
}

While no new dependency instance is created, it is fundamentally the same as new in that no way exists to intercept the call to global.xhr for testing purposes, other then through monkey patching. The basic issue for testing is that a global variable needs to be mutated in order to replace it with call to a mock method. For further explanation of why this is bad see:Brittle Global State & Singletons

The class above is hard to test since we have to change the global state:

var oldXHR = global.xhr;
global.xhr = function mockXHR() {};
var myClass = new MyClass();
myClass.doWork();
// assert that mockXHR got called with the right arguments
global.xhr = oldXHR; // if you forget this bad things will happen

Service Registry:

It may seem that this can be solved by having a registry of all the services and then having the tests replace the services as needed.

function MyClass() {
  var serviceRegistry = ????;
  this.doWork = function() {
    var xhr = serviceRegistry.get('xhr');
    xhr({
      method:'...',
      url:'...',
      complete:function(response){ ... }
    })
}

However, where does the serviceRegistry come from? If it is: new-ed up, the test has no chance to reset the services for testing. a global look-up then the service returned is global as well (but resetting is easier, since only one global variable exists to be reset).

The class above is hard to test since we have to change the global state:

var oldServiceLocator = global.serviceLocator;
global.serviceLocator.set('xhr', function mockXHR() {});
var myClass = new MyClass();
myClass.doWork();
// assert that mockXHR got called with the right arguments
global.serviceLocator = oldServiceLocator; // if you forget this bad things will happen

Passing in Dependencies:

Last, the dependency can be passed in.

function MyClass(xhr) {
  this.doWork = function() {
    xhr({
      method:'...',
      url:'...',
      complete:function(response){ ... }
    })
}

This is the preferred method since the code makes no assumptions about the origin of xhr and cares instead about whoever created the class responsible for passing it in. Since the creator of the class should be different code than the user of the class, it separates the responsibility of creation from the logic. This is dependency-injection in a nutshell.

The class above is testable, since in the test we can write:

function xhrMock(args) {...}
var myClass = new MyClass(xhrMock);
myClass.doWork();
// assert that xhrMock got called with the right arguments

Notice that no global variables were harmed in the writing of this test.

Angular comes with dependency injection built-in, making the right thing easy to do, but you still need to do it if you wish to take advantage of the testability story.

Controllers

What makes each application unique is its logic, and the logic is what we would like to test. If the logic for your application contains DOM manipulation, it will be hard to test. See the example below:

function PasswordCtrl() {
  // get references to DOM elements
  var msg = $('.ex1 span');
  var input = $('.ex1 input');
  var strength;
 
  this.grade = function() {
    msg.removeClass(strength);
    var pwd = input.val();
    password.text(pwd);
    if (pwd.length > 8) {
      strength = 'strong';
    } else if (pwd.length > 3) {
      strength = 'medium';
    } else {
      strength = 'weak';
    }
    msg
     .addClass(strength)
     .text(strength);
  }
}

The code above is problematic from a testability point of view since it requires your test to have the right kind of DOM present when the code executes. The test would look like this:

var input = $('<input type="text"/>');
var span = $('<span>');
$('body').html('<div class="ex1">')
  .find('div')
    .append(input)
    .append(span);
var pc = new PasswordCtrl();
input.val('abc');
pc.grade();
expect(span.text()).toEqual('weak');
$('body').empty();

In angular the controllers are strictly separated from the DOM manipulation logic and this results in a much easier testability story as the following example shows:

function PasswordCtrl($scope) {
  $scope.password = '';
  $scope.grade = function() {
    var size = $scope.password.length;
    if (size > 8) {
      $scope.strength = 'strong';
    } else if (size > 3) {
      $scope.strength = 'medium';
    } else {
      $scope.strength = 'weak';
    }
  };
}

and the test is straight forward:

var $scope = {};
var pc = $controller('PasswordCtrl', { $scope: $scope });
$scope.password = 'abc';
$scope.grade();
expect($scope.strength).toEqual('weak');

Notice that the test is not only much shorter, it is also easier to follow what is happening. We say that such a test tells a story, rather then asserting random bits which don’t seem to be related.

Filters

Filters are functions which transform the data into a user readable format. They are important because they remove the formatting responsibility from the application logic, further simplifying the application logic.

myModule.filter('length', function() {
  return function(text){
    return (''+(text||'')).length;
  }
});
 
var length = $filter('length');
expect(length(null)).toEqual(0);
expect(length('abc')).toEqual(3);

Directives

Directives in angular are responsible for encapsulating complex functionality within custom HTML tags, attributes, classes or comments. Unit tests are very important for directives because the components you create with directives may be used throughout your application and in many different contexts.

Simple HTML Element Directive

Let’s start with an angular app with no dependencies.

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

Now we can add a directive to our app.

app.directive('aGreatEye', function () {
    return {
        restrict: 'E',
        replace:  true,
        template: '<h1>lidless, wreathed in flame, {{1 + 1}} times</h1>'
    };
});

This directive is used as a tag <a-great-eye></a-great-eye>. It replaces the entire tag with the template<h1>lidless, wreathed in flame, {{1 + 1}} times</h1>. Now we are going to write a jasmine unit test to verify this functionality. Note that the expression {{1 + 1}} times will also be evaluated in the rendered content.

describe('Unit testing great quotes', function() {
    var $compile;
    var $rootScope;
 
    // Load the myApp module, which contains the directive
    beforeEach(module('myApp'));
 
    // Store references to $rootScope and $compile
    // so they are available to all tests in this describe block
    beforeEach(inject(function(_$compile_, _$rootScope_){
      // The injector unwraps the underscores (_) from around the parameter names when matching
      $compile = _$compile_;
      $rootScope = _$rootScope_;
    }));
    
    it('Replaces the element with the appropriate content', function() {
        // Compile a piece of HTML containing the directive
        var element = $compile("<a-great-eye></a-great-eye>")($rootScope);
        // fire all the watches, so the scope expression {{1 + 1}} will be evaluated
        $rootScope.$digest();
        // Check that the compiled element contains the templated content
        expect(element.html()).toContain("lidless, wreathed in flame, 2 times");
    });
});

We inject the $compile service and $rootScope before each jasmine test. The $compile service is used to render the aGreatEye directive. After rendering the directive we ensure that the directive has replaced the content and “lidless, wreathed in flame, 2 times” is present.

Sample project

See the angular-seed project for an example.

AngularJS: End-to-end Testing

[Fuente: http://docs.angularjs.org/guide/dev_guide.e2e-testing]

If you’re starting a new Angular project, you may want to look into using Protractor, as it is going to replace the current method of E2E Testing in the near future.

As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to verify the correctness of new features, catch bugs and notice regressions.

To solve this problem, we have built an Angular Scenario Runner which simulates user interactions that will help you verify the health of your Angular application.

Overview

You will write scenario tests in JavaScript, which describe how your application should behave, given a certain interaction in a specific state. A scenario is comprised of one or more it blocks (you can think of these as the requirements of your application), which in turn are made of commands and expectations. Commands tell the Runner to do something with the application (such as navigate to a page or click on a button), and expectations tell the Runner to assert something about the state (such as the value of a field or the current URL). If any expectation fails, the runner marks the it as “failed” and continues on to the next one. Scenarios may also have beforeEach and afterEach blocks, which will be run before (or after) each it block, regardless of whether they pass or fail.

In addition to the above elements, scenarios may also contain helper functions to avoid duplicating code in the it blocks.

Here is an example of a simple scenario:

describe('Buzz Client', function() {
it('should filter results', function() {
  input('user').enter('jacksparrow');
  element(':button').click();
  expect(repeater('ul li').count()).toEqual(10);
  input('filterText').enter('Bees');
  expect(repeater('ul li').count()).toEqual(1);
});
});

Note that input('user') finds the <input> element with ng-model="user" not name="user".

This scenario describes the requirements of a Buzz Client, specifically, that it should be able to filter the stream of the user. It starts by entering a value in the input field with ng-model=”user”, clicking the only button on the page, and then it verifies that there are 10 items listed. It then enters ‘Bees’ in the input field with ng-model=’filterText’ and verifies that the list is reduced to a single item.

The API section below lists the available commands and expectations for the Runner.

API

Source: https://github.com/angular/angular.js/blob/master/src/ngScenario/dsl.js

pause()

Pauses the execution of the tests until you call resume() in the console (or click the resume link in the Runner UI).

sleep(seconds)

Pauses the execution of the tests for the specified number of seconds.

browser().navigateTo(url)

Loads the url into the test frame.

browser().navigateTo(url, fn)

Loads the URL returned by fn into the testing frame. The given url is only used for the test output. Use this when the destination URL is dynamic (that is, the destination is unknown when you write the test).

browser().reload()

Refreshes the currently loaded page in the test frame.

browser().window().href()

Returns the window.location.href of the currently loaded page in the test frame.

browser().window().path()

Returns the window.location.pathname of the currently loaded page in the test frame.

browser().window().search()

Returns the window.location.search of the currently loaded page in the test frame.

browser().window().hash()

Returns the window.location.hash (without #) of the currently loaded page in the test frame.

browser().location().url()

Returns the $location.url() of the currently loaded page in the test frame.

browser().location().path()

Returns the $location.path() of the currently loaded page in the test frame.

browser().location().search()

Returns the $location.search() of the currently loaded page in the test frame.

browser().location().hash()

Returns the $location.hash() of the currently loaded page in the test frame.

expect(future).{matcher}

Asserts the value of the given future satisfies the matcher. All API statements return a future object, which get avalue assigned after they are executed. Matchers are defined using angular.scenario.matcher, and they use the value of futures to run the expectation. For example:expect(browser().location().href()).toEqual('http://www.google.com'). Available matchers are presented further down this document.

expect(future).not().{matcher}

Asserts the value of the given future satisfies the negation of the matcher.

using(selector, label)

Scopes the next DSL element selection.

binding(name)

Returns the value of the first binding matching the given name.

input(name).enter(value)

Enters the given value in the text field with the corresponding ng-model name.

input(name).check()

Checks/unchecks the checkbox with the corresponding ng-model name.

input(name).select(value)

Selects the given value in the radio button with the corresponding ng-model name.

input(name).val()

Returns the current value of an input field with the corresponding ng-model name.

repeater(selector, label).count()

Returns the number of rows in the repeater matching the given jQuery selector. The label is used for test output.

repeater(selector, label).row(index)

Returns an array with the bindings in the row at the given index in the repeater matching the given jQuery selector. Thelabel is used for test output.

repeater(selector, label).column(binding)

Returns an array with the values in the column with the given binding in the repeater matching the given jQueryselector. The label is used for test output.

select(name).option(value)

Picks the option with the given value on the select with the given ng-model name.

select(name).options(value1, value2…)

Picks the options with the given values on the multi select with the given ng-model name.

element(selector, label).count()

Returns the number of elements that match the given jQuery selector. The label is used for test output.

element(selector, label).click()

Clicks on the element matching the given jQuery selector. The label is used for test output.

element(selector, label).query(fn)

Executes the function fn(selectedElements, done), where selectedElements are the elements that match the given jQuery selector and done is a function that is called at the end of the fn function. The label is used for test output.

element(selector, label).{method}()

Returns the result of calling method on the element matching the given jQuery selector, where method can be any of the following jQuery methods: valtexthtmlheightinnerHeightouterHeightwidthinnerWidth,outerWidthpositionscrollLeftscrollTopoffset. The label is used for test output.

element(selector, label).{method}(value)

Executes the method passing in value on the element matching the given jQuery selector, where method can be any of the following jQuery methods: valtexthtmlheightinnerHeightouterHeightwidthinnerWidth,outerWidthpositionscrollLeftscrollTopoffset. The label is used for test output.

element(selector, label).{method}(key)

Returns the result of calling method passing in key on the element matching the given jQuery selector, where methodcan be any of the following jQuery methods: attrpropcss. The label is used for test output.

element(selector, label).{method}(key, value)

Executes the method passing in key and value on the element matching the given jQuery selector, where methodcan be any of the following jQuery methods: attrpropcss. The label is used for test output.

Matchers

Matchers are used in combination with the expect(...) function as described above and can be negated with not(). For instance: expect(element('h1').text()).not().toEqual('Error').

Source: https://github.com/angular/angular.js/blob/master/src/ngScenario/matchers.js

// value and Object comparison following the rules of angular.equals().
expect(value).toEqual(value)
 
// a simpler value comparison using ===
expect(value).toBe(value)
 
// checks that the value is defined by checking its type.
expect(value).toBeDefined()
 
// the following two matchers are using JavaScript's standard truthiness rules
expect(value).toBeTruthy()
expect(value).toBeFalsy()
 
// verify that the value matches the given regular expression. The regular
// expression may be passed in form of a string or a regular expression
// object.
expect(value).toMatch(expectedRegExp)
 
// a check for null using ===
expect(value).toBeNull()
 
// Array.indexOf(...) is used internally to check whether the element is
// contained within the array.
expect(value).toContain(expected)
 
// number comparison using < and >
expect(value).toBeLessThan(expected)
expect(value).toBeGreaterThan(expected)

Example

See the angular-seed project for more examples.

Conditional actions with element(…).query(fn)

E2E testing with angular scenario is highly asynchronous and hides a lot of complexity by queueing actions and expectations that can handle futures. From time to time, you might need conditional assertions or element selection. Even though you should generally try to avoid this (as it is can be sign for unstable tests), you can add conditional behavior with element(...).query(fn). The following code listing shows how this function can be used to delete added entries (where an entry is some domain object) using the application’s web interface.

Imagine the application to be structured into two views:

beforeEach(function () {
  var deleteEntry = function () {
    browser().navigateTo('/entries');
 
    // we need to select the <tbody> element as it might be the case that there
    // are no entries (and therefore no rows). When the selector does not
    // result in a match, the test would be marked as a failure.
    element('table tbody').query(function (tbody, done) {
      // ngScenario gives us a jQuery lite wrapped element. We call the
      // `children()` function to retrieve the table body's rows
      var children = tbody.children();
 
      if (children.length > 0) {
        // if there is at least one entry in the table, click on the link to
        // the entry's detail view
        element('table tbody a').click();
        // and, after a route change, click the delete button
        element('.btn-danger').click();
      }
 
      // if there is more than one entry shown in the table, queue another
      // delete action.
      if (children.length > 1) {
        deleteEntry();
      }
 
      // remember to call `done()` so that ngScenario can continue
      // test execution.
      done();
    });
 
  };
 
  // start deleting entries
  deleteEntry();
});

In order to understand what is happening, we should emphasize that ngScenario calls are not immediately executed, but queued (in ngScenario terms, we would be talking about adding future actions). If we had only one entry in our table, then the following future actions would be queued:

// delete entry 1
browser().navigateTo('/entries');
element('table tbody').query(function (tbody, done) { ... });
element('table tbody a');
element('.btn-danger').click();

For two entries, ngScenario would have to work on the following queue:

// delete entry 1
browser().navigateTo('/entries');
element('table tbody').query(function (tbody, done) { ... });
element('table tbody a');
element('.btn-danger').click();
 
    // delete entry 2
    // indented to represent "recursion depth"
    browser().navigateTo('/entries');
    element('table tbody').query(function (tbody, done) { ... });
    element('table tbody a');
    element('.btn-danger').click();

Caveats

ngScenario does not work with apps that manually bootstrap using angular.bootstrap. You must use the ng-app directive.

AngularJS : From jQuery to Angular

1. Don’t design your page, and then change it with DOM manipulations

In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.

But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking “I have this piece of the DOM and I want to make it do X”, you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.

2. Don’t augment jQuery with AngularJS

Similarly, don’t start with the idea that jQuery does X, Y, and Z, so I’ll just add AngularJS on top of that for models and controllers. This is really tempting when you’re just starting out, which is why I always recommend that new AngularJS developers don’t use jQuery at all, at least until they get used to doing things the “Angular Way”.

I’ve seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $applys that are confusing and convoluted; but they eventually get it working! The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.

The bottom line is this: when solutioning, first “think in AngularJS”; if you can’t think of a solution, ask the community; if after all of that there is no easy solution, then feel free to reach for the jQuery. But don’t let jQuery become a crutch or you’ll never master AngularJS.

3. Always think in terms of architecture

First know that single-page applications are applications. They’re not webpages. So we need to think like a server-side developer in addition to thinking like a client-side developer. We have to think about how to divide our application into individual, extensible, testable components.

So then how do you do that? How do you “think in AngularJS”? Here are some general principles, contrasted with jQuery.

The view is the “official record”

In jQuery, we programmatically change the view. We could have a dropdown menu defined as a ul like so:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

In jQuery, in our application logic, we would activate it with something like:

$('.main-menu').dropdownMenu();

When we just look at the view, it’s not immediately obvious that there is any functionality here. For small applications, that’s fine. But for non-trivial applications, things quickly get confusing and hard to maintain.

In AngularJS, though, the view is the official record of view-based functionality. Our ul declaration would look like this instead:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

These two do the same thing, but in the AngularJS version anyone looking at the template knows what’s supposed to happen. Whenever a new member of the development team comes on board, she can look at this and then know that there is a directive called dropdownMenu operating on it; she doesn’t need to intuit the right answer or sift through any code. The view told us what was supposed to happen. Much cleaner.

Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them. The developer is always flabbergasted when we reply: you don’t. But the reason you don’t do that is that this is like half-jQuery, half-AngularJS, and no good. The problem here is that the developer is trying to “do jQuery” in the context of AngularJS. That’s never going to work well. The view is the official record. Outside of a directive (more on this below), you never, ever, never change the DOM. And directives are applied in the view, so intent is clear.

Remember: don’t design, and then mark up. You must architect, and then design.

Data binding

This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section. AngularJS will automatically update your view so you don’t have to! In jQuery, we respond to events and then update content. Something like:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

For a view that looks like this:

<ul class="messages" id="log">
</ul>

Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before. But more importantly, we had to manually reference and update a DOM node. And if we want to delete a log entry, we have to code against the DOM for that too. How do we test the logic apart from the DOM? And what if we want to change the presentation?

This a little messy and a trifle frail. But in AngularJS, we can do this:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

And our view can look like this:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

But for that matter, our view could look like this:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

And now instead of using an unordered list, we’re using Bootstrap alert boxes. And we never had to change the controller code! But more importantly, no matter where or how the log gets updated, the view will change too. Automatically. Neat!

Though I didn’t show it here, the data binding is two-way. So those log messages could also be editable in the view just by doing this: <input ng-model="entry.msg" />. And there was much rejoicing.

Distinct model layer

In jQuery, the DOM is kind of like the model. But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view. This helps for the above data binding, maintains separation of concerns, and introduces far greater testability. Other answers mentioned this point, so I’ll just leave it at that.

Separation of concerns

And all of the above tie into this over-arching theme: keep your concerns separate. Your view acts as the official record of what is supposed to happen (for the most part); your model represents your data; you have a service layer to perform reusable tasks; you do DOM manipulation and augment your view with directives; and you glue it all together with controllers. This was also mentioned in other answers, and the only thing I would add pertains to testability, which I discuss in another section below.

Dependency injection

To help us out with separation of concerns is dependency injection (DI). If you come from a server-side language (from Java to PHP) you’re probably familiar with this concept already, but if you’re a client-side guy coming from jQuery, this concept can seem anything from silly to superfluous to hipster. But it’s not. 🙂

From a broad perspective, DI means that you can declare components very freely and then from any other component, just ask for an instance of it and it will be granted. You don’t have to know about loading order, or file locations, or anything like that. The power may not immediately be visible, but I’ll provide just one (common) example: testing.

Let’s say in our application, we require a service that implements server-side storage through a REST API and, depending on application state, local storage as well. When running tests on our controllers, we don’t want to have to communicate with the server – we’re testing the controller, after all. We can just add a mock service of the same name as our original component, and the injector will ensure that our controller gets the fake one automatically – our controller doesn’t and needn’t know the difference.

Speaking of testing…

4. Test-driven development – always

This is really part of section 3 on architecture, but it’s so important that I’m putting it as its own top-level section.

Out of all of the many jQuery plugins you’ve seen, used, or written, how many of them had an accompanying test suite? Not very many because jQuery isn’t very amenable to that. But AngularJS is.

In jQuery, the only way to test is often to create the component independently with a sample/demo page against which our tests can perform DOM manipulation. So then we have to develop a component separately and then integrate it into our application. How inconvenient! So much of the time, when developing with jQuery, we opt for iterative instead of test-driven development. And who could blame us?

But because we have separation of concerns, we can do test-driven development iteratively in AngularJS! For example, let’s say we want a super-simple directive to indicate in our menu what our current route is. We can declare what we want in our view:

<a href="/hello" when-active>Hello</a>

Okay, now we can write a test:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

We run our test and confirm that it fails. So now we can write our directive:

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Our test now passes and our menu performs as requested. Our development is both iterative and test-driven. Wicked-cool.

5. Conceptually, directives are not packaged jQuery

You’ll often hear “only do DOM manipulation in a directive”. This is a necessity. Treat it with due deference!

But let’s dive a little deeper…

Some directives just decorate what’s already in the view (think ngClass) and therefore sometimes do DOM manipulation straight away and then are basically done. But if a directive is like a “widget” and has a template, it should also respect separation of concerns. That is, the template too should remain largely independent from its implementation in the link and controller functions.

AngularJS comes with an entire set of tools to make this very easy; with ngClass we can dynamically update the class; ngBind allows two-way data binding; ngShow and ngHide programmatically show or hide an element; and many more – including the ones we write ourselves. In other words, we can do all kinds of awesomeness without DOM manipulation. The less DOM manipulation, the easier directives are to test, the easier they are to style, the easier they are to change in the future, and the more re-usable and distributable they are.

I see lots of developers new to AngularJS using directives as the place to throw a bunch of jQuery. In other words, they think “since I can’t do DOM manipulation in the controller, I’ll take that code put it in a directive”. While that certainly is much better, it’s often still wrong.

Think of the logger we programmed in section 3. Even if we put that in a directive, we still want to do it the “Angular Way”. It still doesn’t take any DOM manipulation! There are lots of times when DOM manipulation is necessary, but it’s a lot rarer than you think! Before doing DOM manipulation anywhere in your application, ask yourself if you really need to. There might be a better way.

Here’s a quick example that shows the pattern I see most frequently. We want a toggleable button. (Note: this example is a little contrived and a skosh verbose to represent more complicated cases that are solved in exactly the same way.)

.directive( 'myDirective', function () {
    return {
        template: '<a>Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                if ( on ) {
                    $(element).removeClass( 'active' );
                }
                else {
                    $(element).addClass( 'active' );
                }

                on = !on;
            });
        }
    };
});

There are a few things wrong with this. First, jQuery was never necessary. There’s nothing we did here that needed jQuery at all! Second, even if we already have jQuery on our page, there’s no reason to use it here; we can simply use angular.element and our component will still work when dropped into a project that doesn’t have jQuery. Third, even assuming jQuery was required for this directive to work, jqLite (angular.element) willalways use jQuery if it was loaded! So we needn’t use the $ – we can just use angular.element. Fourth, closely related to the third, is that jqLite elements needn’t be wrapped in $ – the element that is passed to thelink function would already be a jQuery element! And fifth, which we’ve mentioned in previous sections, why are we mixing template stuff into our logic?

This directive can be rewritten (even for very complicated cases!) much more simply like so:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

Again, the template stuff is in the template, so you (or your users) can easily swap it out for one that meets any style necessary, and the logic never had to be touched. Reusability – boom!

And there are still all those other benefits, like testing – it’s easy! No matter what’s in the template, the directive’s internal API is never touched, so refactoring is easy. You can change the template as much as you want without touching the directive. And no matter what you change, your tests still pass.

w00t!

So if directives aren’t just collections of jQuery-like functions, what are they? Directives are actually extensions of HTML. If HTML doesn’t do something you need it to do, you write a directive to do it for you, and then use it just as if it was part of HTML.

Put another way, if AngularJS doesn’t do something out of the box, think how the team would accomplish it to fit right in with ngClickngClass, et al.

Summary

Don’t even use jQuery. Don’t even include it. It will hold you back. And when you come to a problem that you think you know how to solve in jQuery already, before you reach for the $, try to think about how to do it within the confines the AngularJS. If you don’t know, ask! 19 times out of 20, the best way to do it doesn’t need jQuery and to try to solve it with jQuery results in more work for you.

AngularJS: Notes On AngularJS Scope Life-Cycle

[Fuente: http://onehungrymind.com/notes-on-angularjs-scope-life-cycle/]

I have had the incredible good fortune of being part of some very talented developers ramping up on AngularJS. It is inevitable that questions surrounding scope life-cycle work their way into the process. These usually come in the form of “But how does AngularJS know when this value has changed so that it can update bindings?” or “Hey I am listening for this DOM event in my directive and when I update scope, nothing is happening… what is the deal?” or even “Oh my goodness! How does it do that!? IS IT MAGIC!?”

At the core of AngularJS is the scope life-cycle and so I wanted to take this opportunity to elaborate on some of the fundamental aspects of how scope works in AngularJS. I have tried to distill this concept down to the most important bits so that a new developer could grasp scope life-cycle in less than 10 minutes and experienced developers could explain it in less than 10 minutes.

First Things First

Misko Hevery wrote a brilliant explanation of dirty checking vs change listeners on Stack Overflow that I think should be required reading for anyone coming into AngularJS. I hereby vote that it be included in the AngularJS docs IMMEDIATELY!

http://stackoverflow.com/questions/9682092/databinding-in-angularjs/9693933#9693933

I want to point out a few things as it relates to what I want to talk about here:

  1. AngularJS compares a value with its previous value and if it has changed then a change event is fired. This is dirty checking in a nutshell.
  2. In AngularJS, a digest is the cycle that performs dirty checking. This is initiated via $digest().
  3. If something happens outside of AngularJS, you need to let AngularJS know to execute a digest cycle and you do that via $apply which calls $digest.

Now on to the nuts and bolts! I think that the scope life-cycle IS dirty checking and all the broad strokes can be summarized in $digest, watchExpressions and $apply.

$digest

This is the “heartbeat” of an AngularJS application. $digest processes all the watchExpressions for the current scope and its children.

So what happens when a watchExpression is processed? I will get into that a bit more when I talk about watchExpressions, but basically the value of the current watchExpression is compared with the value of the previous watchExpression, and if they do not match then it is “dirty” and a listener is fired.

With that said, you should not call $digest directly but call $apply which will force a $digest cycle. I will get more into the reasoning behind this in just a moment.

watchExpressions

Behind every $digest cycle is a good watchExpression. watchExpressions return the value of what is being watched on every $digest cycle. This is the trenches of dirty checking. If the value of the current watchExpression call and the previous watchExpression call do not match then a listener is fired.

Most watchExpressions are created implicitly within AngularJS, but you can also create them manually. Let me show you how to do that:

1
scope.$watch(‘name’, function(newValue, oldValue) { /* Do something clever here */ });

Most of the time a watchExpression is just the name of a property you want to watch. In this example the watchExpression is “name”. If “name” changes then the listener function is called.

angular.equals is used to determine the equality of the two expressions while angular.copy is used to store the value of current value of a watchExpression for later comparison.

It is also important to understand that when one listener fires, it may change the model which will fire other listeners and so the watchers keep re-running until no more watchers are firing.

$apply

I like to think of $apply as a courier service that the outside world can recruit to tell AngularJS that something has happened and drop off an optional expression to be handled.

I mentioned previously that you use $apply to force a $digest cycle, but that is just one part of what happens with $apply. To follow the courier analogy, $apply hand delivers the message and possibly a package to the sweet lady at the front desk named $evalerie, but you can call her $eval. GROAN! Okay! Back on track! $eval checks to make sure that $apply dropped off a legitimate expression. If something is wrong while it is being evaluated then an exception is thrown and passed to the $exceptionHandler service. From there, $digest is called to kick off the $digest cycle.

Application level error handling is a nice feature that I highly recommend you utilize, especially as your application grows in complexity. The fact that we get it for free with $apply is really cool and why you should use it over $digest.

So when do you use $apply?

Good question! One of the main reasons you use $apply is when browser DOM events have triggered outside of AngularJS. jQuery I’m looking at you!

You may also need to use it for setTimeout events, XHR callbacks, and integrating with 3rd party libraries.

Here is a fiddle I put together to illustrate a use of $apply
http://jsfiddle.net/simpulton/huKHQ/

I freely admit that this example is a bit contrived – it stems from a real question my buddy Fritz had a few days ago.

The part I want to draw your attention to is in the code below:

1
2
3
4
5
6
7
8
9
$(‘.testButtonWithApply’).on(‘click’, function(){
$scope.$apply(function() {
$scope.handleClick(‘Scope apply’);
});
});

$(‘.testButtonWithoutApply’).on(‘click’, function(){
$scope.handleClick(‘This will not work’);
});

Both functions are listening for events via jQuery and then making a request back into AngularJS from the event handler. The difference between the two is that I have wrapped the handleClick function in a function expression that I pass to $apply. I could have just called handleClick and THEN $apply but it is better to use the function expression so you get error handling.

More than once calling $apply has been the difference between me getting the behavior I expected, and crickets as nothing happened at all.

Conclusion

This concludes my primer on AngularJS scope life-cycle and what is behind the “magic” that blew me away when I started digging into AngularJS.

So to summarize, there is an internal cycle called $digest that runs through the application and executes watch expressions and compares the value returned with the previous value and if the values do not match then a listener is fired. This $digest cycle keeps looping until no more listeners are fired. You can call $digest directly, but it is recommended that you call $apply because it wraps a $digest call with an error handling mechanism. You call $apply when something outside of AngularJS happens that you need to notify AngularJS about. Well, I guess when you say it like that… it doesn’t seem so hard. Cheers!

Resources

The Misko Hevery Breakdown
http://stackoverflow.com/questions/9682092/databinding-in-angularjs/9693933#9693933

$apply Example
http://jsfiddle.net/simpulton/huKHQ/

And be sure to check out the documentation. I have read it like ten times and am still learning things.
http://docs.angularjs.org/api/ng.$rootScope.Scope

AngularJS: Building Huuuuuge Apps with AngularJS

[Fuente: http://briantford.com/blog/huuuuuge-angular-apps.html]

The AngularJS documentation is great for getting started and for looking up specific API calls. However, it doesn’t really tell you how to organize and manage your app as it grows to tens or hundreds of thousands of lines of code. I’ve collected here some of my observations and best practices for how to manage your sprawling application. First we’ll take a look at organization, then move on to some tips on improving performance, and conclude with a brief summary on tools, servers, and build processes. While this post will focus on big apps in particular, there’s a great video on YouTube from the December 2012 AngularJS meetup on best practices that’s also worth checking out.

Don’t Write a Huge App

The best advice about huge apps is not to make them. Write small, focused, modular parts, and progressively combine them into bigger things to make your app. (This advice brought to you by node.js hacker and all around cool dude @substack)

Organization

Probably the biggest question with large apps is where to put all of that code. On your toolbelt of organizational tools, you’ve got files, directories, modules, services, and controllers. For a quick overview of good AngularJS project structure, check out the Angular Seed on Github. However I’d like to go a bit more in-depth and offer some additional advice on project structure. Let’s start with directories and work our way down the list.

Directories

This is the typical folder layout that I recommend:

root-app-folder
├── index.html
├── scripts
│   ├── controllers
│   │   └── main.js
│   │   └── ...
│   ├── directives
│   │   └── myDirective.js
│   │   └── ...
│   ├── filters
│   │   └── myFilter.js
│   │   └── ...
│   ├── services
│   │   └── myService.js
│   │   └── ...
│   ├── vendor
│   │   ├── angular.js
│   │   ├── angular.min.js
│   │   ├── es5-shim.min.js
│   │   └── json3.min.js
│   └── app.js
├── styles
│   └── ...
└── views
    ├── main.html
    └── ...

As you add more files, it might make sense to create subdirectories to further organize controllers and services. For instance, I often find myself making a models directory inside of services. My rule of thumb is to only further sort files into directories if there is some rational hierarchy by which you can organize the files.

Files

Each file should have one “thing” in it, where a “thing” is a controller, directive, filter, or service. This makes for small, focused files. It also helps create a litmus test for how APIs are doing. If you find yourself flipping back and forth through files too frequently, this is an indication that your APIs are too complex. You should rethink, refactor, and simplify.

I would make an exception for closely related directives. For example, if you have an <pane> directive that requires <panel> to be a parent, those should be in the same file.

Modules

Define and configure all modules in app.js:

angular.module('yourAppName', ['yourAppDep']);
angular.module('yourAppDep');

Define controllers, services, etc. on modules like this:

angular.module('yourAppDep').controller('MyCtrl', function () {
  // ...
});

Although we (the AngularJS team) have discussed being able to lazy-load at the module granularity, it’s not yet on the roadmap for the next version of Angular. There was a good discussion on Google+ about using multiple top-level AngularJS apps to produce a lazy-loading-like effect. I haven’t tried it or seen it done, but if you desperately need to reduce payload size, that’s certainly one way to do it.

The only remaining question is how to subdivide controllers, directives, services, and filters into modules. The Angular Seed puts filters, services, and directives into separate modules, but that seems a bit silly to me. Depending on the app, I’d be more inclined to organize modules by page/route. From a performance perspective, it doesn’t really matter how you organize your modules, so choose whatever method best suits your project.

Dependencies

In general, services, controllers, directives, etc. should have as few dependencies as possible. This is good software development practice in general, but it’s worth mentioning. This also will help in testing.

APIs should be layered. Controllers especially should not be synthesizing different levels of abstraction.

Directives

Use an app-specific prefix for directives. This is useful for avoiding collisions with 3rd party components. On the subject of 3rd party components, there’s a growing community site called ngmodules that looks promising.

For example, if your app is called “The Best Todo List App Ever,” you might prefix your directives with “btla.”

angular.module('yourAppDep').directive('btlaControlPanel', function () {
  // ...
});

You might worry about directive names becoming too long, but I haven’t seen it become problematic. You’ll never really see a performance hit from long directive names, thanks to gzip compression.

Services

angular.module('yourAppDep').service('MyCtrl', function () {
  // ...
});

Models

AngularJS is unique among JavaScript frameworks in that it gives you complete control over your model layer. I think this is one of the great strengths of Angular, because at the core of your application is your data, and data varies wildly from app to app. My biggest recommendation is to consider what data you will be using, and how you will store it.

If you’re using a NoSQL datastore like CouchDB or MongoDB, you might be content working with plain-old JavaScript Objects (POJO) and functional helpers. If you’re using a relational database like MySQL, you might want psuedo-classes with methods for mutating, serializing, and deserializing the data. If your server provides a RESTful interface, $resource might be a good place to start. These are just suggestions; any of these approaches might be useful outside of the situations I described. With so many options, this is sometimes a challenging decision to make. But thinking hard about your data will pay off.

In general, you’ll find many great utilities for dealing with models in Underscore.js, the utility library that also powers Backbone.js.

Controllers

By convention, controller names should start with a capital letter and end with “Ctrl”.

angular.module('yourAppDep').controller('MyCtrl', function () {
  // ...
});

Remember that controllers can be reused. This seems obvious, but I’ve caught myself reimplementing features in different controllers. For example, consider a user control panel that allows a user to change application settings and a dialog box prompting a user to change a setting. Both could share a common controller.

Performance

AngularJS apps are generally very, very fast. Most apps really don’t need any sort of special optimization, so unless you’re experiencing poor performance, your time is better spent improving your app in other ways. For these exceptional cases Angular provides some excellent ways to address performance issues. First though, it’s important to identify the cause of performance degradation. For that, I highly recommend the AngularJS Batarang Chrome extension or Chrome’s built-in CPU profiling.

Optimizing the Digest Cycle

AngularJS uses dirty checking in its “digest cycle.” For the uninitiated, you can read more about the digest cycle in the official docs and in this StackOverflow answer.

Sometimes, you want to be able to avoid a digest cycle. One common situation in real-time WebSocket’ed apps is that you don’t always want to digest when you receive a message. Consider a real-time game where messages are sent from the server 30 or more times per second.

app.factory('socket', function ($rootScope) {
  var socket = io.connect();
  return {
    on: function (eventName, callback) {
      socket.on(eventName, function () {  // this could fire many times a second
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      });
    }
    // ...
  };
});

One great way to deal with this is to “throttle” the requests so a digest only happens a few times a second. Underscore.js provides such a function, but the implementation is pretty tiny, so I’ve reproduced it inside the socket service below:

app.factory('socket', function ($rootScope) {

  // Underscore.js 1.4.3
  // http://underscorejs.org
  // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
  // Underscore may be freely distributed under the MIT license.

  // _.throttle
  // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626
  // Returns a function, that, when invoked, will only be triggered at most once
  // during a given window of time.
  var throttle = function (func, wait) {
    var context, args, timeout, result;
    var previous = 0;
    var later = function() {
      previous = new Date();
      timeout = null;
      result = func.apply(context, args);
    };
    return function() {
      var now = new Date();
      var remaining = wait - (now - previous);
      context = this;
      args = arguments;
      if (remaining <= 0) {
        clearTimeout(timeout);
        timeout = null;
        previous = now;
        result = func.apply(context, args);
      } else if (!timeout) {
        timeout = setTimeout(later, remaining);
      }
      return result;
    };
  };

  var socket = io.connect();
  return {
    on: function (eventName, callback) {
      socket.on(eventName, throttle(function () {  // limit to once every 500ms
        var args = arguments;
        $rootScope.$apply(function () {
          callback.apply(socket, args);
        });
      }, 500));
    }
    // ...
  };
});

Other times, you know an incoming change will only affect certain scopes, and might want to just dirty check those. For those cases, you can call $scope.$digest instead of $scope.$apply$digest will only run the digest cycle on the scope it’s called on, and all of that scope’s children.

Finally, to keep digest cycles short, watch expressions in $scope.$watch should be as fast as possible. Wherever possible, avoid deep comparisons. Remember, you only need to compare things that affect the view.

Filters

Filters are called at least twice during every digest cycle. For that reason, it’s best if they are lightweight.

In cases where data is loaded and displayed, but not modified, moving the transformations done in filters to run on the data when it’s fetched might be better. This is actually relatively simple, since AngularJS exposes filters to be used programmatically through $filter.

For instance, you load a list of names in lower-case, but need title-case, so you have a filter that does the transformation:

{{someModel.name | titlecase}}

It’s pretty easy to move this to your controller and change the name to title-case when it’s loaded.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) {
  $http.get('/someModel')
    .success(function (data) {
      $scope.someModel = data;
      // run the same "titlecase" filter inside the controller after loading the data
      $scope.someModel.name = $filter('titlecase')($scope.someModel.name);
    });
});

For cases that you can’t transform data upon retrieval, memoization is a great way to speed up your expensive filters without much work. Addy Osmani has a pretty great article on memoization in JavaScript that’s worth a read. As for implementation, Underscore.js provides an excellent memoization function that you can use. This technique should not be used blindly, however. Memoization only helps when you’re calling a filter frequently with the same, unchanged models. For rapidly changing models that have many different values throughout your application’s runtime, you’re better off not memoizing filters that act on that data.

Testing

Testing is immensely important for large projects. Tests allow you to refactor with confidence, which is essential in keeping code clean on a large project. Large apps should have both unit and end-to-end (E2E) tests. Unit tests are great in helping you pinpoint problems, and E2E tests ensure that the whole app works as expected. Each controller, service, filter, and directive should have a set of unit tests. Each feature of your app should have an E2E test.

This is another topic that deserves more attention. Fortunately, the AngularJS documentation has more to say on both unit and E2E tests. My colleage Vojta Jina also spoke recently about testing directives. The video is on YouTube, and definitely worth a watch.

Tools

I’ve been doing a lot of work on Yeoman to try to consolidate best practices and good project structure, and make what little boilerplate AngularJS has automagically generated. I highly recommend checking it out.

The AngularJS Batarang is another of my projects, and is great for both debugging and finding performance bottlenecks.

Server

As you’re aware, you can use any server you want with AngularJS. It is strictly a client-side library. My recommendation and prefered setup is to use Node.js alongside nginx. I use nginx to server static files, and Node to create a RESTful API and/or socketed app. Node.js hits a sweet spot between ease of use and speed. For instance, it’s relatively easy to spawn worker processes or create a webserver that can use all of your fancy server’s cores.

As for cloud providers, I’ve used both Nodejitsu and Linode to great success. Nodejitsu is great if you’re sticking strictly to node. It makes deploying your app easy, and you don’t have to worry about your server environment. You can spawn additional node processes as needed to scale and handle bigger loads. If you need more control over your server environment, Linode gives you root to a fleet of VMs. Linode also provides a nice API for managing VMs. And there are plenty of other great cloud server providers that I haven’t had a chance to look at yet myself.

Configuring and scaling a backend is a subject worthy of its own article, and there’s no shortage of great advice elsewhere for that.

Build Process

Admittedly, this is one thing Angular needs to be better at, and one of my huge aims for 2013 is to help on this front. I’ve released ngmin, a tool that I hope will ultimately solve the problem of minimizing AngularJS apps for production.

For now, I think your best bet is concatenating your JavaScript files with app.js first, then using ngmin to annotate DI functions, and finally minifying with Closure Compiler with the flag--compilation_level SIMPLE_OPTIMIZATIONS. You can see an example of this at work in the build process for angular.js.

I don’t recommend using RequireJS with AngularJS. Although it’s certainly possible, I haven’t seen any instance where RequireJS was beneficial in practice.

Conclusion

AngularJS is one of the most suitable JS frameworks for writing large apps. Out-of-the-box, it’s very fast and greatly helps structure your app. But hopefully this advice is useful as you push the boundaries for what’s possible with AngularJS.

Have some advice for scaling Angular apps? Tweetemail, or send a pull request on Github.

AngularJS: Creating Custom Directives

[Fuente: http://docs.angularjs.org/guide/directive ]

Note: this guide is targeted towards developers who are already familiar with AngularJS basics. If you’re just getting started, we recommend the tutorial first. If you’re looking for the directives API, we recently moved it to$compile.

This document explains when you’d want to create your own directives in your AngularJS app, and how to implement them.

What are Directives?

At a high level, directives are markers on a DOM element (such as an attribute, element name, or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.

Angular comes with a set of these directives built-in, like ngBindngModel, and ngView. Much like you create controllers and services, you can create your own directives for Angular to use. When Angular bootstraps your application, the HTML compiler traverses the DOM matching directives against the DOM elements.

What does it mean to “compile” an HTML template? For AngularJS, “compilation” means attaching event listeners to the HTML to make it interactive. The reason we use the term “compile” is that the recursive process of attaching directives mirrors the process of compiling source code in compiled programming languages.

Matching Directives

Before we can write a directive, we need to know how Angular’s HTML compiler determines when to use a given directive.

In the following example, we say that the <input> element matches the ngModel directive.

<input ng-model="foo">

The following also matches ngModel:

<input data-ng:model="foo">

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:

  1. Strip x- and data- from the front of the element/attributes.
  2. Convert the :-, or _-delimited name to camelCase.

Here are some equivalent examples of elements that match ngBind:

index.html

<!doctype html>
<html ng-app="docsBindExample">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl1">
      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/>
    </div>
  </body>
</html>
scripts.js
angular.module('docsBindExample', [])
  .controller('Ctrl1', function Ctrl1($scope) {
    $scope.name = 'Max Karl Ernst Ludwig Planck (April 23, 1858 – October 4, 1947)';
  });
Best Practice: Prefer using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool, you can instead use the data-prefixed version (e.g. data-ng-bind for ngBind). The other forms shown above are accepted for legacy reasons but we advise you to avoid them.

$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. The following demonstrates the various ways a directive (myDir in this case) can be referenced from within a template:

<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span></span>

Best Practice: Prefer using directives via tag name and attributes over comment and class names. Doing so generally makes it easier to determine what directives a given element matches.

Best Practice: Comment directives were commonly used in places where the DOM API limits the ability to create directives that spanned multiple elements (e.g. inside <table> elements). AngularJS 1.2 introduces ng-repeat-start and ng-repeat-end as a better solution to this problem. Developers are encouraged to use this over custom comment directives when possible.

Text and attribute bindings

During the compilation process the compiler matches text and attributes using the $interpolate service to see if they contain embedded expressions. These expressions are registered as watches and will update as part of normal digest cycle. An example of interpolation is shown below:

<a ng-href="img/{{username}}.jpg">Hello {{username}}!</a>

ngAttr attribute bindings

Web browsers are sometimes picky about what values they consider valid for attributes.

For example, considering this template:

<svg>
  <circle cx="{{cx}}"></circle>
</svg>

We would expect Angular to be able to bind to this, but when we check the console we see something likeError: Invalid value for attribute cx="{{cx}}". Because of the SVG DOM API’s restrictions, you cannot simply write cx="{{cx}}".

With ng-attr-cx you can work around this problem.

If an attribute with a binding is prefixed with the ngAttr prefix (denormalized as ng-attr-) then during the binding will be applied to the corresponding unprefixed attribute. This allows you to bind to attributes that would otherwise be eagerly processed by browsers (e.g. an SVG element’s circle[cx] attributes).

For example, we could fix the example above by instead writing:

<svg>
  <circle ng-attr-cx="{{cx}}"></circle>
</svg>

Creating Directives

First let’s talk about the API for registering directives. 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.

The factory function is invoked only once when the compiler matches the directive for the first time. You can perform any initialization work here. The function is invoked using $injector.invoke which makes it injectable just like a controller.

Best Practice: Prefer using the definition object over returning a function.We’ll go over a few common examples of directives, then dive deep into the different options and compilation process.

Best Practice: In order to avoid collisions with some future standard, it’s best to prefix your own directive names. For instance, if you created a <carousel> directive, it would be problematic if HTML7 introduced the same element. A two or three letter prefix (e.g. btfCarousel) works well. Similarly, do not prefix your own directives with ng or they might conflict with directives included in a future version of Angular.

For the following examples, we’ll use the prefix my (e.g. myCustomer).

Template-expanding directive

Let’s say you have a chunk of your template that represents a customer’s information. This template is repeated many times in your code. When you change it in one place, you have to change it in several others. This is a good opportunity to use a directive to simplify your template.

Let’s create a directive that simply replaces its contents with a static template:

Source

index.html

<!doctype html>
<html ng-app="docsSimpleDirective">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl">
      <div my-customer></div>
    </div>
  </body>
</html>
scripts.js
angular.module('docsSimpleDirective', [])
  .controller('Ctrl', function($scope) {
    $scope.customer = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
  })
  .directive('myCustomer', function() {
    return {
      template: 'Name: {{customer.name}} Address: {{customer.address}}'
    };
  });

Notice that we have bindings in this directive. After $compile compiles and links <div my-customer> </div>, it will try to match directives on the element’s children. This means you can compose directives of other directives. We’ll see how to do that in an example below.

In the example above we in-lined the value of the template option, but this will become annoying as the size of your template grows.

Best Practice: Unless your template is very small, it’s typically better to break it apart into its own HTML file and load it with the templateUrl option.If you are familiar with ngIncludetemplateUrl works just like it. Here’s the same example using templateUrl instead:

<!doctype html>
<html ng-app="docsTemplateUrlDirective">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl">
      <div my-customer></div>
    </div>
  </body>
</html>
Name: {{customer.name}} Address: {{customer.address}}
angular.module('docsTemplateUrlDirective', [])
  .controller('Ctrl', function($scope) {
    $scope.customer = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
  })
  .directive('myCustomer', function() {
    return {
      templateUrl: 'my-customer.html'
    };
  });

Great! But what if we wanted to have our directive match the tag name <my-customer> instead? If we simply put a <my-customer> element into the HTML, it doesn’t work.

Note: When you create a directive, it is restricted to attribute only by default. In order to create directives that are triggered by element name, you need to use the restrict option.

The restrict option is typically set to:

  • 'A' – only matches attribute name
  • 'E' – only matches element name
  • 'AE' – matches either attribute or element name

Let’s change our directive to use restrict: 'E':

Source

<!doctype html>
<html ng-app="docsRestrictDirective">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl">
      <my-customer></my-customer>
    </div>
  </body>
</html>
angular.module('docsRestrictDirective', [])
  .controller('Ctrl', function($scope) {
    $scope.customer = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
  })
  .directive('myCustomer', function() {
    return {
      restrict: 'E',
      templateUrl: 'my-customer.html'
    };
  });

For more on the restrict property, see the API docs.

When should I use an attribute versus an element? Use an element when you are creating a component that is in control of the template. The common case for this is when you are creating a Domain-Specific Language for parts of your template. Use an attribute when you are decorating an existing element with new functionality.

Using an element for the myCustomer directive is clearly the right choice because you’re not decorating an element with some “customer” behavior; you’re defining the core behavior of the element as a customer component.

Isolating the Scope of a Directive

Our myCustomer directive above is great, but it has a fatal flaw. We can only use it once within a given scope.In its current implementation, we’d need to create a different controller each time In order to re-use such a directive:

Source

<!doctype html>
<html ng-app="docsScopeProblemExample">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="NaomiCtrl">
      <my-customer></my-customer>
    </div>
    <hr>
    <div ng-controller="IgorCtrl">
      <my-customer></my-customer>
    </div>
  </body>
</html>

Name: Naomi Address: 1600 Amphitheatre

Name: Igor Address: 123 Somewhere

This is clearly not a great solution.

What we want to be able to do is separate the scope inside a directive from the scope outside, and then map the outer scope to a directive’s inner scope. We can do this by creating what we call an isolate scope. To do this, we can use a directive’s scope option:

Source

<!doctype html>
<html ng-app="docsIsolateScopeDirective">
<head>
<script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
	<div ng-controller="Ctrl">
		<my-customer info="naomi"></my-customer>
		<hr>
		<my-customer info="igor"></my-customer>
	</div>
</body>
</html>
Name: {{customerInfo.name}} Address: {{customerInfo.address}}
angular.module('docsIsolateScopeDirective', []).controller('Ctrl',
		function($scope) {
			$scope.naomi = {
				name : 'Naomi',
				address : '1600 Amphitheatre'
			};
			$scope.igor = {
				name : 'Igor',
				address : '123 Somewhere'
			};
		}).directive('myCustomer', function() {
	return {
		restrict : 'E',
		scope : {
			customerInfo : '=info'
		},
		templateUrl : 'my-customer-iso.html'
	};
});

Demo

Name: Naomi Address: 1600 Amphitheatre


Name: Igor Address: 123 Somewhere

Looking at index.html, the first <my-customer> element binds the info attribute to naomi, which we have exposed on our controller’s scope. The second binds info to igor.

Let’s take a closer look at the scope option:

//...
scope: {
  customerInfo: '=info'
},
//...

The scope option is an object that contains a property for each isolate scope binding. In this case it has just one property:

  • Its name (customerInfo) corresponds to the directive’s isolate scope property customerInfo.
  • Its value (=info) tells $compile to bind to the info attribute.
Note: These =attr attributes in the scope option of directives are normalized just like directive names. To bind to the attribute in <div bind-to-this="thing">, you’d specify a binding of =bindToThis.

For cases where the attribute name is the same as the value you want to bind to inside the directive’s scope, you can use this shorthand syntax:

...
scope: {
  // same as '=customer'
  customer: '='
},
...

Besides making it possible to bind different data to the scope inside a directive, using an isolated scope has another effect.

We can show this by adding another property, vojta, to our scope and trying to access it from within our directive’s template:

Source

<!doctype html>
<html ng-app="docsIsolationExample">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl">
      <my-customer info="naomi"></my-customer>
    </div>
  </body>
</html>
Name: {{customerInfo.name}} Address: {{customerInfo.address}}
<hr>
Name: {{vojta.name}} Address: {{vojta.address}}
angular.module('docsIsolationExample', [])
  .controller('Ctrl', function($scope) {
    $scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };

    $scope.vojta = { name: 'Vojta', address: '3456 Somewhere Else' };
  })
  .directive('myCustomer', function() {
    return {
      restrict: 'E',
      scope: {
        customerInfo: '=info'
      },
      templateUrl: 'my-customer-plus-vojta.html'
    };
  });

Demo

Name: Naomi Address: 1600 Amphitheatre


Name: Address:

Notice that {{vojta.name}} and {{vojta.address}} are empty, meaning they are undefined. Although we defined vojta in the controller, it’s not available within the directive.

As the name suggests, the isolate scope of the directive isolates everything except models that you’ve explicitly added to the scope: {} hash object. This is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in.

Note: Normally, a scope prototypically inherits from its parent. An isolated scope does not. See the “Isolating the Scope of a Directive” section for more information about isolate scopes.

Best Practice: Use the scope option to create isolate scopes when making components that you want to reuse throughout your app.

Creating a Directive that Manipulates the DOM

In this example we will build a directive that displays the current time. Once a second, it updates the DOM to reflect the current time.

Directives that want to modify the DOM typically use the link optionlink takes a function with the following signature,

function link(scope, element, attrs) { ... }

where:

  • scope is an Angular scope object.
  • element is the jqLite-wrapped element that this directive matches.
  • attrs is an object with the normalized attribute names and their corresponding values.

In our link function, we want to update the displayed time once a second, or whenever a user changes the time formatting string that our directive binds to. We will use the $interval service to call a handler on a regular basis. This is easier than using $timeout but also works better with end 2 end testing, where we want to ensure that all $timeouts have completed before completing the test. We also want to remove the $interval if the directive is deleted so we don’t introduce a memory leak.

Source

<!doctype html>
<html ng-app="docsTimeDirective">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl2">
      Date format: <input ng-model="format"> <hr/>
      Current time is: <span my-current-time="format"></span>
    </div>
  </body>
</html>
angular.module('docsTimeDirective', [])

.controller('Ctrl2', function($scope) {
	$scope.format = 'M/d/yy h:mm:ss a';
})

.directive('myCurrentTime', function($interval, dateFilter) {

	function link(scope, element, attrs) {
		var format, timeoutId;

		function updateTime() {
			element.text(dateFilter(new Date(), format));
		}

		scope.$watch(attrs.myCurrentTime, function(value) {
			format = value;
			updateTime();
		});

		element.on('$destroy', function() {
			$interval.cancel(timeoutId);
		});

		// start the UI update process; save the timeoutId for canceling
		timeoutId = $interval(function() {
			updateTime(); // update DOM
		}, 1000);
	}

	return {
		link : link
	};
});

Demo

Date format: 


Current time is: 1/21/14 4:30:05 PM

There are a couple of things to note here. Just like the module.controller API,  the function argument in module.directive is dependency injected. Because of this, we can use $interval and dateFilter inside our directive’s link function.

We register an event element.on('$destroy', ...). What fires this $destroy event?

There are a few special events that AngularJS emits. When a DOM node that has been compiled with Angular’s compiler is destroyed, it emits a $destroy event. Similarly, when an AngularJS scope is destroyed, it broadcasts a $destroy event to listening scopes.

By listening to this event, you can remove event listeners that might cause memory leaks. Listeners registered to scopes and elements are automatically cleaned up when they are destroyed, but if you registered a listener on a service, or registered a listener on a DOM node that isn’t being deleted, you’ll have to clean it up yourself or you risk introducing a memory leak.

Best Practice: Directives should clean up after themselves. You can use element.on('$destroy', ...) or scope.$on('$destroy', ...) to run a clean-up function when the directive is removed.

Creating a Directive that Wraps Other Elements

We’ve seen that you can pass in models to a directive using the isolate scope, but sometimes it’s desirable to be able to pass in an entire template rather than a string or an object. Let’s say that we want to create a “dialog box” component. The dialog box should be able to wrap any arbitrary content.

To do this, we need to use the transclude option.

Source

<!doctype html>
<html ng-app="docsTransclusionDirective">
<head>
<script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
	<div ng-controller="Ctrl">
		<my-dialog>Check out the contents, {{name}}!</my-dialog>
	</div>
</body>
</html>
<div class="alert" ng-transclude>
</div>
angular.module('docsTransclusionDirective', [])
  .controller('Ctrl', function($scope) {
    $scope.name = 'Tobias';
  })
  .directive('myDialog', function() {
    return {
      restrict: 'E',
      transclude: true,
      templateUrl: 'my-dialog.html'
    };
  });

Demo

Check out the contents, Tobias!

What does this transclude option do, exactly? transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

To illustrate this, see the example below. Notice that we’ve added a link function in script.js that redefines name as Jeff. What do you think the {{name}} binding will resolve to now?

Source

<!doctype html>
<html ng-app="docsTransclusionExample">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="Ctrl">
      <my-dialog>Check out the contents, {{name}}!</my-dialog>
    </div>
  </body>
</html>
angular.module('docsTransclusionExample', [])
  .controller('Ctrl', function($scope) {
    $scope.name = 'Tobias';
  })
  .directive('myDialog', function() {
    return {
      restrict: 'E',
      transclude: true,
      scope: {},
      templateUrl: 'my-dialog.html',
      link: function (scope, element) {
        scope.name = 'Jeff';
      }
    };
  });

Demo

Check out the contents, Tobias!

Ordinarily, we would expect that {{name}} would be Jeff. However, we see in this example that the {{name}}binding is still Tobias.

The transclude option changes the way scopes are nested. It makes it so that the contents of a transcluded directive have whatever scope is outside the directive, rather than whatever scope is on the inside. In doing so, it gives the contents access to the outside scope.

Note that if the directive did not create its own scope, then scope in scope.name = 'Jeff'; would reference the outside scope and we would see Jeff in the output.

This behavior makes sense for a directive that wraps some content, because otherwise you’d have to pass in each model you wanted to use separately. If you have to pass in each model that you want to use, then you can’t really have arbitrary contents, can you?

Best Practice: only use transclude: true when you want to create a directive that wraps arbitrary content.

Next, we want to add buttons to this dialog box, and allow someone using the directive to bind their own behavior to it.

Source

<!doctype html>
<html ng-app="docsIsoFnBindExample">
<head>
<script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
	<div ng-controller="Ctrl">
		<my-dialog ng-hide="dialogIsHidden" on-close="hideDialog()">
		Check out the contents, {{name}}! 
		</my-dialog>
	</div>
</body>
</html>
<div class="alert">
  <a href class="close" ng-click="close()">×</a>
  <div ng-transclude></div>
</div>
angular.module('docsIsoFnBindExample', [])
  .controller('Ctrl', function($scope, $timeout) {
    $scope.name = 'Tobias';
    $scope.hideDialog = function () {
      $scope.dialogIsHidden = true;
      $timeout(function () {
        $scope.dialogIsHidden = false;
      }, 2000);
    };
  })
  .directive('myDialog', function() {
    return {
      restrict: 'E',
      transclude: true,
      scope: {
        'close': '&onClose'
      },
      templateUrl: 'my-dialog-close.html'
    };
  });

Demo

×

Check out the contents, Tobias!

We want to run the function we pass by invoking it from the directive’s scope, but have it run in the context of the scope where its registered.

We saw earlier how to use =attr in the scope option, but in the above example, we’re using &attr instead. & bindings expose a function to an isolated scope allowing the isolated scope to invoke it, but maintaining the original scope of the function. So when a user clicks the x in the dialog, it runs Ctrl‘s hideDialog function.

Best Practice: use &attr in the scope option when you want your directive to expose an API for binding to behaviors.

Creating a Directive that Adds Event Listeners

Previously, we used the link function to create a directive that manipulated its DOM elements. Building upon that example, let’s make a directive that reacts to events on its elements.

For instance, what if we wanted to create a directive that lets a user drag an element?

Source

<!doctype html>
<html ng-app="dragModule">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <span my-draggable>Drag ME</span>
  </body>
</html>
angular.module('dragModule', []).
  directive('myDraggable', function($document) {
    return function(scope, element, attr) {
      var startX = 0, startY = 0, x = 0, y = 0;

      element.css({
       position: 'relative',
       border: '1px solid red',
       backgroundColor: 'lightgrey',
       cursor: 'pointer'
      });

      element.on('mousedown', function(event) {
        // Prevent default dragging of selected content
        event.preventDefault();
        startX = event.pageX - x;
        startY = event.pageY - y;
        $document.on('mousemove', mousemove);
        $document.on('mouseup', mouseup);
      });

      function mousemove(event) {
        y = event.pageY - startY;
        x = event.pageX - startX;
        element.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }

      function mouseup() {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
      }
    }
  });

Creating Directives that Communicate

You can compose any directives by using them within templates.

Sometimes, you want a component that’s built from a combination of directives.

Imagine you want to have a container with tabs in which the contents of the container correspond to which tab is active.

Source

<!doctype html>
<html ng-app="docsTabsExample">
  <head>
    <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <my-tabs>
      <my-pane title="Hello">
        <h5 id="creating-custom-directives_source_hello">Hello</h5>
        <p>Lorem ipsum dolor sit amet</p>
      </my-pane>
      <my-pane title="World">
        <h5 id="creating-custom-directives_source_world">World</h5>
        <em>Mauris elementum elementum enim at suscipit.</em>
        <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
      </my-pane>
    </my-tabs>
  </body>
</html>
<div class="tabbable">
  <ul class="nav nav-tabs">
    <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
      <a href="" ng-click="select(pane)">{{pane.title}}</a>
    </li>
  </ul>
  <div class="tab-content" ng-transclude></div>
</div>
<div class="tab-pane" ng-show="selected" ng-transclude>
</div>
angular.module('docsTabsExample', [])
  .directive('myTabs', function() {
    return {
      restrict: 'E',
      transclude: true,
      scope: {},
      controller: function($scope) {
        var panes = $scope.panes = [];
 
        $scope.select = function(pane) {
          angular.forEach(panes, function(pane) {
            pane.selected = false;
          });
          pane.selected = true;
        };
 
        this.addPane = function(pane) {
          if (panes.length == 0) {
            $scope.select(pane);
          }
          panes.push(pane);
        };
      },
      templateUrl: 'my-tabs.html'
    };
  })
  .directive('myPane', function() {
    return {
      require: '^myTabs',
      restrict: 'E',
      transclude: true,
      scope: {
        title: '@'
      },
      link: function(scope, element, attrs, tabsCtrl) {
        tabsCtrl.addPane(scope);
      },
      templateUrl: 'my-pane.html'
    };
  });

The myPane directive has a require option with value ^myTabs. When a directive uses this option, $compile will throw an error unless the specified controller is found. The ^ prefix means that this directive searches for the controller on its parents (without the ^ prefix, the directive would look for the controller on just its own element).

So where does this myTabs controller come from? Directives can specify controllers using the unsurprisingly named controller option. As you can see, the myTabs directive uses this option. Just like ngController, this option attaches a controller to the template of the directive.

Looking back at myPane‘s definition, notice the last argument in its link function: tabsCtrl. When a directive requires a controller, it receives that controller as the fourth argument of its link function. Taking advantage of this,myPane can call the addPane function of myTabs.

Savvy readers may be wondering what the difference is between link and controller. The basic difference is that controller can expose an API, and link functions can interact with controllers using require.

Best Practice: use controller when you want to expose an API to other directives. Otherwise use link.

Summary

Here we’ve seen the main use cases for directives. Each of these samples acts as a good starting point for creating your own directives.

You might also be interested in an in-depth explanation of the compilation process that’s available in the compiler guide.

The $compile API page has a comprehensive list of directive options for reference.