Author Archives: admin

Abstract Factory Design Pattern in Java

[Fuente: http://www.journaldev.com/1418/abstract-factory-design-pattern-in-java]

 

Abstract Factory is one of the Creational pattern and almost similar to Factory Pattern except the fact that its more like factory of factories.

If you are familiar with factory design pattern in java, you will notice that we have a single Factory class that returns the different sub-classes based on the input provided and factory class uses if-else or switch statement to achieve this.

In Abstract Factory pattern, we get rid of if-else block and have a factory class for each sub-class and then an Abstract Factory class that will return the sub-class based on the input factory class. At first it seems confusing but once you see the implementation, its really easy to grasp and understand the minor difference between Factory and Abstract Factory pattern.

Like our factory pattern post, we will use the same super class and sub-classes.

Super Class and Sub-Classes

Computer.java
package com.journaldev.design.model;  
public abstract class Computer {
      
    public abstract String getRAM();
    public abstract String getHDD();
    public abstract String getCPU();
      
    @Override
    public String toString(){
        return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
    }
}
PC.java
package com.journaldev.design.model;   
public class PC extends Computer {
  
    private String ram;
    private String hdd;
    private String cpu;
      
    public PC(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }
  
    @Override
    public String getHDD() {
        return this.hdd;
    }
  
    @Override
    public String getCPU() {
        return this.cpu;
    }
  
}
Server.java
package com.journaldev.design.model;    
public class Server extends Computer {
  
    private String ram;
    private String hdd;
    private String cpu;
      
    public Server(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }
  
    @Override
    public String getHDD() {
        return this.hdd;
    }
  
    @Override
    public String getCPU() {
        return this.cpu;
    }
  
}

Factory Classes for Each sub-class

First of all we need to create a Abstract Factory interface or abstract class.

ComputerAbstractFactory.java
package com.journaldev.design.abstractfactory;
 
import com.journaldev.design.model.Computer;
 
public interface ComputerAbstractFactory {
 
    public Computer createComputer();
 
}

Notice that createComputer() method is returning an instance of super class Computer. Now our factory classes will implement this interface and return their respective sub-class.

PCFactory.java
package com.journaldev.design.abstractfactory;
 
import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;
 
public class PCFactory implements ComputerAbstractFactory {
 
    private String ram;
    private String hdd;
    private String cpu;
     
    public PCFactory(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public Computer createComputer() {
        return new PC(ram,hdd,cpu);
    }
 
}

Similarly we will have a factory class for Server sub-class.

 
ServerFactory.java
package com.journaldev.design.abstractfactory;
 
import com.journaldev.design.model.Computer;
import com.journaldev.design.model.Server;
 
public class ServerFactory implements ComputerAbstractFactory {
 
    private String ram;
    private String hdd;
    private String cpu;
     
    public ServerFactory(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
     
    @Override
    public Computer createComputer() {
        return new Server(ram,hdd,cpu);
    }
 
}

Now we will create a consumer class that will provide the entry point for the client classes to create sub-classes.

ComputerFactory.java
package com.journaldev.design.abstractfactory;
 
import com.journaldev.design.model.Computer;
 
public class ComputerFactory {
 
    public static Computer getComputer(ComputerAbstractFactory factory){
        return factory.createComputer();
    }
}

Notice that its a simple class and getComputer method is accepting ComputerAbstractFactory argument and returning Computer object. At this point the implementation must be getting clear.

Lets write a simple test method and see how to use the abstract factory to get the instance of sub-classes.

TestDesignPatterns.java
package com.journaldev.design.test;
 
import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;
 
public class TestDesignPatterns {
 
    public static void main(String[] args) {
        testAbstractFactory();
    }
 
    private static void testAbstractFactory() {
        Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
        Computer server = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new ServerFactory("16 GB","1 TB","2.9 GHz"));
        System.out.println("AbstractFactory PC Config::"+pc);
        System.out.println("AbstractFactory Server Config::"+server);
    }
}

Output of the above program will be:

1
2
AbstractFactory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

Here is the class diagram of abstract factory implementation.

Abstract-Factory-Pattern

Benefits of Abstract Factory Pattern

  • Abstract Factory pattern provides approach to code for interface rather than implementation.
  • Abstract Factory pattern is “factory of factories” and can be easily extended to accommodate more products, for example we can add another sub-class Laptop and a factory LaptopFactory.
  • Abstract Factory pattern is robust and avoid conditional logic of Factory pattern.

Abstract Factory Pattern Examples in JDK

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Factory Design Pattern

 

Factory Pattern is one of the Creational Design pattern and it’s widely used in JDK as well as frameworks like Spring and Struts.

Factory design pattern is used when we have a super class with multiple sub-classes and based on input, we need to return one of the sub-class. This pattern take out the responsibility of instantiation of a class from client program to the factory class. Let’s first learn how to implement factory pattern in java and then we will learn it’s benefits and we will see its usage in JDK.

Super Class

Super class in factory pattern can be an interface, abstract class or a normal java class. For our example, we have super class as abstract class with overridden toString() method for testing purpose.

Computer.java
   
package com.journaldev.design.model;

public abstract class Computer {

public abstract String getRAM();
public abstract String getHDD();
public abstract String getCPU();

@Override
public String toString(){
return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
}
}

Sub Classes

Let’s say we have two sub-classes PC and Server with below implementation.

PC.java
   
package com.journaldev.design.model;


public class PC extends Computer {

private String ram;
private String hdd;
private String cpu;

public PC(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}

@Override
public String getHDD() {
return this.hdd;
}

@Override
public String getCPU() {
return this.cpu;
}

}

Notice that both the classes are extending Computer class.

Server.java
   
package com.journaldev.design.model;


public class Server extends Computer {

private String ram;
private String hdd;
private String cpu;

public Server(String ram, String hdd, String cpu){
this.ram=ram;
this.hdd=hdd;
this.cpu=cpu;
}
@Override
public String getRAM() {
return this.ram;
}

@Override
public String getHDD() {
return this.hdd;
}

@Override
public String getCPU() {
return this.cpu;
}

}

Factory Class

Now that we have super classes and sub-classes ready, we can write our factory class. Here is the basic implementation.

 
ComputerFactory.java
   
package com.journaldev.design.factory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;
import com.journaldev.design.model.Server;

public class ComputerFactory {

public static Computer getComputer(String type, String ram, String hdd, String cpu){
if("PC".equalsIgnoreCase(type)) return new PC(ram, hdd, cpu);
else if("Server".equalsIgnoreCase(type)) return new Server(ram, hdd, cpu);

return null;
}
}
  1. We can keep Factory class Singleton or we can keep the method that returns the subclass as static.
  2. Notice that based on the input parameter, different subclass is created and returned.

factory-pattern-java

Here is a simple test client program that uses above factory pattern implementation.

TestFactory.java
   
package com.journaldev.design.test;

import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;

public class TestFactory {

public static void main(String[] args) {
Computer pc = ComputerFactory.getComputer("pc","2 GB","500 GB","2.4 GHz");
Computer server = ComputerFactory.getComputer("server","16 GB","1 TB","2.9 GHz");
System.out.println("Factory PC Config::"+pc);
System.out.println("Factory Server Config::"+server);
}

}

Output of above program is:

1
2
Factory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

Benefits of Factory Pattern

  1. Factory pattern provides approach to code for interface rather than implementation.
  2. Factory pattern removes the instantiation of actual implementation classes from client code, making it more robust, less coupled and easy to extend. For example, we can easily change PC class implementation because client program is unaware of this.
  3. Factory pattern provides abstraction between implementation and client classes through inheritance.

Factory Pattern Examples in JDK

  1. java.util.Calendar, ResourceBundle and NumberFormat  getInstance() methods uses Factory pattern.
  2. valueOf() method in wrapper classes like Boolean, Integer etc.
 

Java Singleton Design Pattern Best Practices with Examples

[Fuente :http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples]

Singleton is one of the Gangs of Four Design patterns and comes in the Creational Design Pattern category. From the definition, it seems to be a very simple design pattern but when it comes to implementation, it comes with a lot of implementation concerns. The implementation of Singleton pattern has always been a controversial topic among developers. Here we will learn about Singleton design pattern principles, different ways to implement Singleton and some of the best practices for it’s usage.

Singleton Pattern

Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. Singleton pattern is used for logging, drivers objects, caching and thread pool.

Singleton design pattern is also used in other design patterns like Abstract FactoryBuilderPrototype,Facade etc. Singleton design pattern is used in core java classes also, for example java.lang.Runtime,java.awt.Desktop.

Java Singleton Pattern

To implement Singleton pattern, we have different approaches but all of them have following common concepts.

  • Private constructor to restrict instantiation of the class from other classes.
  • Private static variable of the same class that is the only instance of the class.
  • Public static method that returns the instance of the class, this is the global access point for outer world to get the instance of the singleton class.

In further sections, we will learn different approaches of Singleton pattern implementation and design concerns with the implementation.

  1. Eager initialization
  2. Static block initialization
  3. Lazy Initialization
  4. Thread Safe Singleton
  5. Bill Pugh Singleton Implementation
  6. Using Reflection to destroy Singleton Pattern
  7. Enum Singleton
  8. Serialization and Singleton

Eager initialization

In eager initialization, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.

Here is the implementation of static initialization singleton class.

EagerInitializedSingleton.java
package com.journaldev.singleton;

public class EagerInitializedSingleton {

    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();

    //private constructor to avoid client applications to use constructor
    private EagerInitializedSingleton(){}

    public static EagerInitializedSingleton getInstance(){
        return instance;
    }
}

If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios, Singleton classes are created for resources such as File System, Database connections etc and we should avoid the instantiation until unless client calls the getInstance method. Also this method doesn’t provide any options for exception handling.

Static block initialization

Static block initialization implementation is similar to eager initialization, except that instance of class is created in the static block that provides option for exception handling.

StaticBlockSingleton.java
package com.journaldev.singleton;

public class StaticBlockSingleton {

    private static StaticBlockSingleton instance;

    private StaticBlockSingleton(){}

    //static block initialization for exception handling
    static{
        try{
            instance = new StaticBlockSingleton();
        }catch(Exception e){
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
    }

    public static StaticBlockSingleton getInstance(){
        return instance;
    }
}

Both eager initialization and static block initialization creates the instance even before it’s being used and that is not the best practice to use. So in further sections, we will learn how to create Singleton class that supports lazy initialization.

Read: Java static

Lazy Initialization

Lazy initialization method to implement Singleton pattern creates the instance in the global access method. Here is the sample code for creating Singleton class with this approach.

LazyInitializedSingleton.java
package com.journaldev.singleton;

public class LazyInitializedSingleton {

    private static LazyInitializedSingleton instance;

    private LazyInitializedSingleton(){}

    public static LazyInitializedSingleton getInstance(){
        if(instance == null){
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}

The above implementation works fine incase of single threaded environment but when it comes to multithreaded systems, it can cause issues if multiple threads are inside the if loop at the same time. It will destroy the singleton pattern and both threads will get the different instances of singleton class. In next section, we will see different ways to create a thread-safe singleton class.

Thread Safe Singleton

The easier way to create a thread-safe singleton class is to make the global access method synchronized, so that only one thread can execute this method at a time. General implementation of this approach is like the below class.

ThreadSafeSingleton.java
package com.journaldev.singleton;

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;

    private ThreadSafeSingleton(){}

    public static synchronized ThreadSafeSingleton getInstance(){
        if(instance == null){
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }

}

Above implementation works fine and provides thread-safety but it reduces the performance because of cost associated with the synchronized method, although we need it only for the first few threads who might create the separate instances (Read: Java Synchronization). To avoid this extra overhead every time,double checked locking principle is used. In this approach, the synchronized block is used inside the if condition with an additional check to ensure that only one instance of singleton class is created.

Below code snippet provides the double checked locking implementation.
public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
    if(instance == null){
        synchronized (ThreadSafeSingleton.class) {
            if(instance == null){
                instance = new ThreadSafeSingleton();
            }
        }
    }
    return instance;
}

Read: Thread Safe Singleton Class

Bill Pugh Singleton Implementation

Prior to Java 5, java memory model had a lot of issues and above approaches used to fail in certain scenarios where too many threads try to get the instance of the Singleton class simultaneously. So Bill Pugh came up with a different approach to create the Singleton class using a inner static helper class. The Bill Pugh Singleton implementation goes like this;

BillPughSingleton.java
package com.journaldev.singleton;

public class BillPughSingleton {

    private BillPughSingleton(){}

    private static class SingletonHelper{
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance(){
        return SingletonHelper.INSTANCE;
    }
}

Notice the private inner static class that contains the instance of the singleton class. When the singleton class is loaded, SingletonHelper class is not loaded into memory and only when someone calls the getInstance method, this class gets loaded and creates the Singleton class instance.

This is the most widely used approach for Singleton class as it doesn’t require synchronization. I am using this approach in many of my projects and it’s easy to understand and implement also.

Read: Java Nested Classes

Using Reflection to destroy Singleton Pattern

Reflection can be used to destroy all the above singleton implementation approaches. Let’s see this with an example class.

ReflectionSingletonTest.java
package com.journaldev.singleton;

import java.lang.reflect.Constructor;

public class ReflectionSingletonTest {

    public static void main(String[] args) {
        EagerInitializedSingleton instanceOne = EagerInitializedSingleton.getInstance();
        EagerInitializedSingleton instanceTwo = null;
        try {
            Constructor[] constructors = EagerInitializedSingleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                //Below code will destroy the singleton pattern
                constructor.setAccessible(true);
                instanceTwo = (EagerInitializedSingleton) constructor.newInstance();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(instanceOne.hashCode());
        System.out.println(instanceTwo.hashCode());
    }

}

When you run the above test class, you will notice that hashCode of both the instances are not same that destroys the singleton pattern. Reflection is very powerful and used in a lot of frameworks like Spring and Hibernate, do check out Java Reflection Tutorial.

Enum Singleton

To overcome this situation with Reflection, Joshua Bloch suggests the use of Enum to implement Singleton design pattern as Java ensures that any enum value is instantiated only once in a Java program. Since Java Enum values are globally accessible, so is the singleton. The drawback is that the enum type is somewhat inflexible; for example, it does not allow lazy initialization.

EnumSingleton.java
package com.journaldev.singleton;

public enum EnumSingleton {

    INSTANCE;

    public static void doSomething(){
        //do something
    }
}

Read: Java Enum

Serialization and Singleton

Sometimes in distributed systems, we need to implement Serializable interface in Singleton class so that we can store it’s state in file system and retrieve it at later point of time. Here is a small singleton class that implements Serializable interface also.

SerializedSingleton.java
package com.journaldev.singleton;

import java.io.Serializable;

public class SerializedSingleton implements Serializable{

    private static final long serialVersionUID = -7604766932017737115L;

    private SerializedSingleton(){}

    private static class SingletonHelper{
        private static final SerializedSingleton instance = new SerializedSingleton();
    }

    public static SerializedSingleton getInstance(){
        return SingletonHelper.instance;
    }

}

The problem with above serialized singleton class is that whenever we deserialize it, it will create a new instance of the class. Let’s see it with a simple program.

SingletonSerializedTest.java
package com.journaldev.singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class SingletonSerializedTest {

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        SerializedSingleton instanceOne = SerializedSingleton.getInstance();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                "filename.ser"));
        out.writeObject(instanceOne);
        out.close();

        //deserailize from file to object
        ObjectInput in = new ObjectInputStream(new FileInputStream(
                "filename.ser"));
        SerializedSingleton instanceTwo = (SerializedSingleton) in.readObject();
        in.close();

        System.out.println("instanceOne hashCode="+instanceOne.hashCode());
        System.out.println("instanceTwo hashCode="+instanceTwo.hashCode());

    }

}

Output of the above program is;

1
2
instanceOne hashCode=2011117821
instanceTwo hashCode=109647522

So it destroys the singleton pattern, to overcome this scenario all we need to do it provide the implementation of readResolve() method.

protected Object readResolve() {
    return getInstance();
}

After this you will notice that hashCode of both the instances are same in test program.

Read: Java Serialization and Java Deserialization.

I hope this article helps you in grasping fine details of Singleton design pattern, do let me know through your thoughts and comments.

Java Design Patterns – Tutorial con ejemplos

[Fuente: http://www.journaldev.com/1827/]

java-design-patternsLos patrones de diseño son muy populares entre los programadores de software.

  • Un patrón de diseño es una solución bien descrita a un problema común de software.
  • Algunos de los beneficios de utilizar patrones de diseño son:
    • Los patrones de diseño están ya definidos y proporcionados como estándares por la industria para resolver problemas recurrentes, de forma que ahora mucho tiempo.
    • Utilizar patrones de diseño promociona reusabilidad lo cual produce un código más mantenible , robusto y reusable. Ayuda a reducir el total cost of ownership (TCO) of the software product.
    • Ya que los patrones de diseño están ya definidos, hace nuestro código más fácil de entender y depurar. Esto lleva a un desarrollo más rápido y a que si se incorporan nuevos miembros a un equipo les sea fácil entender el código.
  • Los patrones de diseño Java se dividen en tres categorías: creacionales (creational) , estructurales (structural) y de comportamiento (behavioral).En este post haremos un índice a artículos sobre patrones de diseño publicados en otros post.

Creational Design Patterns

Los patrones de diseño creacionales proporcionan una solución para instanciar un objeto de la mejor manera posible en situaciones específicas.

Singleton

El patrón singleton restringe la instanciación de una clase de forma que asegura que solo una instancia de la clase existe en la JVM. Parece un patrón de diseño muy simple pero cuando hay que implementarlo , viene con varios aspectos de implementación a considerar. La implementación de un patrón Singleton supone siempre un tema controvertido entre los programadores. Visita Singleton Design Pattern para aprender más sobre las diferentes formas de implementar este patrón y los pros y las contras de cada uno de los métodos.

Factory

El patrón Factory se utiliza cuando tenemos una super clase con múltiples subclasses y , basándose en la entrada del usuario , necesitamos retornar una de las subclases. Este patrón le da la responsabilidad de la instanciación de una clase del programa cliente a la clase factory. Podemos aplicar el patrón Singleton en la clase Factory o hacer el método factory estático. Visita Factory Design Pattern para ver un ejemplo de un programa y los beneficios de este patrón.

Abstract Factory

El patrón Abstract Factory es similar al patrón Factory ya que es como una factoria de factorias. Si ya conoces el patrón factory en Java , te darás cuenta que tenemos una sola Factory class que retorna las diferentes subclases basandose en la entrada del usuario. La factory class utiliza if-else o la sentencia switch para conseguir esto.

En el patrón Abstract Factory , evitamos los bloques if-else y lo que se hace es tener una factory class por cada subclase y entonces una clase Abstract Factory que retornará la subclase basándose en la factory class de entrada. Visita Abstract Factory Pattern  para conocer cómo se implementa con un programa de ejemplo.

Builder 

Este patrón fue introducido para resolver algunos de los problemas con Factory y Abstract Factory cuando el Object contiene muchos atributos. El patrón Builder resuelve el problema de tener un grán número de parámetros opcionales y estado inconsistente proporcionando una forma de construir el objeto paso a paso y proporcionar un método que retornará el objeto final. Visita Builder Pattern para ver un programa de ejemplo y las clases utilizadas en el JDK.

Prototype 

El patrón Prototipo se utiliza cuando la creación del objeto es un asunto de mucho coste y requiere mucho tiempo y recursos y además tienes un objeto similar ya existente. Así este patrón proporciona un mecanismo para copiar el objeto original a un nuevo objeto y entonces modificarlo de acuerdo a nuestras necesidades. Este patrón utilizar java cloning para copiar el objeto.

Este patrón de diseño obliga a que el objeto que estás copiando debe proporcionar un método de copiado. El copiado no debe ser hecho por otra clase. Sin embargo sobre si utilizar shallow copy o deep copy de las properties del Object depende de los requerimientos y es una decisión de diseño. Visita Prototype Pattern para ver un programa de ejemplo.

Structural Design Patterns

Los patrones estructurales proporcionan distintas formas de crear una estructura de clase, por ejemplo utilizar herencia y composición para crear un objeto grande de objetos pequeños.

Adapter 

El patrón Adapter es utilizado para cuando dos interfaces sin relación tienen que trabajar juntos. El objeto que une estos interfaces se le llama un Adapter. Como ejemplo de la vida real, podemos pensar en un cargador de móvil como un adapter porque la batería del móvil necesita 3 voltios para cargar pero el enchufe normal tiene 120 voltios de salida (EEUU) y 240V (Europa y la India). Asi que el cargador de un móvil funciona como un adapter entre el conector de carga del móvil y el enchufe de la pared. Visita Adapter Pattern  para ver un programa de ejemplo.

Composite 

El patrón composite es uno de los patrones estructurales y es utilizado cuando tenemos que representar una jerarquía part-whole. Cuando tenemos que crear una estructura en la forma de que los objetos de la estructura deben ser tratados de la misma forma, podemos aplicar este patrón.

Lo entenderemos con un ejemplo de la vida real – Un diagrama es una estructura que se compone de Objects como Circle, Lines, Triangles etc y cuando coloreamos (por ejemplo de Red), el mismo color debe ser aplicado a todos los Objects del dibujo. Aquí dibujar es hecho de distintas partes y todos ellos tienen las mismas operaciones. Visita Composite Pattern  para ver distintos componentes de composite y un programa de ejemplo.

Proxy 

Este patrón pretende “Proporcionar un sustituto de otro objeto para controlar el acceso a este“. La definición en si misma es muy clara de forma que se usa este patrón cuando queremos proporcionar acceso controlado de una funcionalidad.

Digamos que tenemos una clase que puede ejecuta algún comando en el sistema. Ahora si estamos utilizándolo, imaginemos que queremos dar este programa a una aplicación cliente, puede haber entonces varios problemas gordos cuando el programa cliente puede facilitar comandos para borrar ficheros del sistema o cambiar algunas settings que no son deseables. Visita Proxy Pattern para ver más detalles.

Flyweight 

Este patrón es utilizado cuando necesitamos crear varios Objects de una clase. Ya que cada objeto consume espacio de memoria que puede ser crucial para dispositivos con pocos recursos de memoria, como por ejemplo dispositivos móviles, el patrón flyweight puede ser apli Flyweight Pattern .

Facade 

El patrón Facade es utilizado para ayudar a las aplicaciones cliente interactuen fácilmente con el sistema. Supongamos que tenemos una aplicación con un conjunto de interfaces para utilizar bases de datos Mysql / Oracle y generar distintos tipos de informes, como por ejemplo un informe HTML , un PDF , etc. Asi tenemos varis conjuntos de interfaces con distintos tipos de bases de datos. Ahora una aplicación cliente puede utilizar estos interfaces para pedir conexión a la base de datos y generar informes. Pero cuando la complejidad se incrementa o los nombres de los interfaces son confusos, la aplicación cliente encontrará difícil utilizarlos. Asi podemos aplicar el patrón Facade para un proporcionar un wrapper interface encima del interface existente para ayudar a la aplicación cliente. Visita el Facade Pattern para ver detalles de implementación y programa de ejemplo.

Bridge 

Cuando tenemos jerarquías de interfaces tanto en interfaces como en implementaciones, entonces el patrón Builder se utiliza para desacoplar los interfaces de la implementación y esconder los detalles de implementación a los programas cliente. Como el patrón Adapter, es uno de los patrones estructurales.La implementación del patrón Bridge sigue la noción de preferir Composition sobre la herencia. Visita Bridge Pattern para más detalles de implementación y un programa de ejemplo.

Decorator 

El patrón Decorator se utiliza para modificar la funcionalidad de un objeto en tiempo de ejecución. Al mismo tiempo otras instancias de la misma clase no serán afectados por esto, así que el objeto individual condigue realizar el comportamiento modificado. El patrón Decorator es uno de los patrones estructurales y utiliza las abstract classes o los interfaces con la composition para ser implementado.

Utilizamos herencia o composition para extender el comportamiento de un objeto pero esto es hecho en tiempo de compilación y es aplicable a todas las instancias de la clase. No podemos añadir ninguna nueva funcionalidad o borrar alguna existente en tiempo de ejecución – aqui es donde el patrón Decorator entra en escena. Visita Decorator Pattern para ver un ejemplo de programa y detalles de implementación.

Behavioral Design Patterns

Los patrones de comportamiento proporcionan solución para que haya mejor interacción entre los objetos y como proporcionar poco acople y flexibilidad se haga de forma fácil.

Template Method

  • El template Method es utilizado para crear un método stub y delegar algunos de los pasos de la implementación a las subclases. El Template method define los pasos para ejecutar un algoritmo y puede proporcionar una implementación por defecto que podría ser común a todas o a algunas de las subclases.

Supongamos que queremos proporcionar un algoritmo para construir una casa. Los pasos necesarios a ser realizados para construir una casa son  – construir el diseño , construir los pilares , construir los muros y las ventanas. El punto importante es que no podemos cambiar el orden de ejecución porque no podemos poner las ventanas antes de construir la base. asi que en este caso podemos crear un template method que usará distintos métodos para construir la casa. Visita Template Method Pattern para ver más detalles de implementación.

Mediator 

  • El patrón Mediator se utiliza para proporcionar un medio de comunicación centralizada entre distintos objetos en un sistema. Estos patrones de diseño son muy útiles cuando en una aplicación corporativa hay varios objetos que están interactuando los unos con los otros. Si los objetos interactuan entre ellos directamente, los componentes del sistema quedan muy acoplados entre llos lo que hace que la mantenibilidad sea costosa y muy poco flexible de extender. El patrón Mediator se enfoca en proporcionar un mediator entre los objetos para que se comuniquen y les ayuda a tener poco acoplamiento entre ellos.

Los controladores aereos son un grans ejemplo de mediator donde la torre de control funciona como un mediator para que exista comunicación entre los distintos vuelos. Mediator funciona como un router entre objetos y puede tener su propia lógica para proporcionar una forma de comunicación determinada. Visita Mediator Pattern para más detalles.

Chain of Responsibility 

Este patrón se utiliza para conseguir desacople en el diseño de un software donde una request de un cliente es pasada a una cadena de objetos para que sea procesada. Entonces el objeto de la cadena decide cada uno por si mismo quien procesará la request y si la request requiere ser enviada al siguiente objeto de la cadena o no.

Sabemos que tenemos varios catch blocks en un bloque de código try-catch. Aquí cada bloque catch es como un procesador que procesa una excepción en particular. así cuando cualquier excepción ocurre en el bloque try, es enviada al promer bloque catch para que sea procesada. Si ese catch block no puede procesarla, la pasa la siguiente objeto de la cadena, es decir el siguiente bloque catch. Si incluso el último bloque catch de la cadena no puede procesar la excepción, la excepción es enviada fuera de la cadena del programa que invoca.

Los cajeros automáticos (ATM) pueden ser implementadas utilizando Chain of Responsibility Pattern, visita ese link para más detalles.

Observer 

El patrón Observer es útil cuando estás interesado en el estado de un objeto y queremos ser notificados cuando haya algún cambio. En este patrón , el objeto que observa el estado de otro objeto es llamado el Observer y el objeto siendo observado el Subject.

Java proporciona en su core la implementación de Observer a través de la clase java.util.Observable y el interfaz java.util.Observer.Sin embargo no es ampliamente utilizado porque la implementación es muy simple y la mayoría de las veces no queremos finalizar ampliando una clase solo para implementar el patrón Observer ya que java no proporciona herencia múltiple en las clases.

El  Java Message Service (JMS) utiliza Observer junto con el patrón Mediator para permitir a las aplicaciones suscribirse y publicar datos en otras aplicaciones. Visita Observer Pattern para más detalles y un ejemplo de implementación.

Strategy 

El patrón Strategy se utiliza cuando tenemos varios algoritmos para realizar una tarea específica y el cliente decide qué implementación va a ser utilizada en tiempo de ejecución.

El patrón Strategy también es conocido como el patrón Policy. Definimos varios algoritmos y permite a una aplicación cliente pasar el algoritmo a ser utilizado como un parámetro. Uno de los mejores ejemplos de este patrón es el método Collections.sort() que recibe el parámetro Comparator. Basándose en las implementaciones distintas de los interfaces Comparator , los objetos son ordenados de distintas formas. Visita Strategy Pattern para más detalles.

Command 

Este patrón se utiliza para implementar desacople en un modelo de request-response. En este patrón, la request se envía al invocador y es el invocador el que la pasa al objeto Command encapsulado. El objeto Command pasa la request al método apropiado del Receiver para realizar la acción específica.

Digamos quee queremos proporcionar una utilizada de sistema de ficheros con métodos para abrir , escribir y cerrar ficheros y que debe funcionar para múltiples sistemas operativos tales como Windows o unix.

Para implementar nuestra utilidad de File System , lo primero de todo que necesitamos es crear las clases receiver que harán todo el trabajo. Ya que codificamos en términos de interfaces java, podemos tener un interfaz FileSystemReceiver y sus clases de implementación para distintos sistemas operativos. Visita  Command Pattern para más detalles.

State 

El patrón de State se utiliza cuando un objeto cambia su comportamiento basándose en su estado interno.

Si tenemos que cambiar el comportamiento de un objeto basándose en su estado , podemos tener una variable de estado en el Object y utilizar un bloque de condiciones if-else para realizar diferentes acciones basadas en el estado. Este patrón se utiliza para proporcionar un forma sistematica y desacoplada de conseguirlo a través de las implementaciones Context t State. Visita  State Pattern para más detalles.

Visitor

Este patrón se utiliza cuando tenemos que realizar una operación sobre un grupo similar de objects. Con la ayuda del patrón Visitor, podemos mover la lógica operacional desde los objetos a otra clase.

Por ejemplo, pensemos de un carrito de la compra donde podemos añadir distintos tipos de productos (Elements) , cuando clicamos en el botón de comprar,  calcula la cantidad total a ser pagada. Ahora podemos tener la lógica de cálculo en las clases que modelan los productos o podemos mover está lógica a otra clase utilizando el patrón Visitor. Veamos ejemplo en  Visitor Pattern para más detalles de implementación.

Interpreter 

Se utiliza para definir una representación gramátical para un lenguaje y proporciona un interprete para tratar con esta gramática.

El mejor ejemplo de esta patrón es un java compiler que interpreta el código fuente java en byte code entendible por la JVM. Google Translator es también un ejemplo de interprete donde la entrada puede ser en cualquier lenguaje y podemos dar la salida interpretada en otro lenguaje. Visita Interpreter Pattern

Iterator

Es utilizado para proporcionar una forma estandar para recorrer un grupo de objetos. Este patrón se utiliza bastante en las  Java Collection Framework donde el Iterator interfaz proporciona métodos para recorridos a través de una colección.

El patrón Iterator no es sólo sobre recorrer colecciones , podemos proporcionar distintos tipos de iterator basándonos en nuestros requerimientos.El patrón Iterator esconde la implementación actual de recorrido a través de una colección y los programas cliente sólo utilizan los métodos del iterator. Visita Iterator Pattern.

Memento 

Este patrón se utiliza cuando queremos salvar el estado de un objeto de forma que podamos recuperarlo más tarde. Este patrón implementa esta solución de tal forma que el estado grabado del objeto no es accesible fuera del objeto, esto protege la integridad de los datos de estado guardados.

Se implementa con dos objetos –  Originator y Caretaker. Originator es el objeto del cual necesitamos su estado para ser grabado y recuperado y que utiliza una clase inner para guardar el estado de un Object. Esta inner class es llamada Memento y es privada , asi que no puede ser accedida desde otros objetos. Visita Memento Pattern.

GAE: Google Cloud Storage

About Google Cloud Storage (GCS)

Google Cloud Storage is useful for storing and serving large files. Additionally, Cloud Storage offers the use of access control lists (ACLs), and the ability to resume upload operations if they’re interrupted, and many other features. (The GCS client library makes use of this resume capability automatically for your app, providing you with a robust way to stream data into GCS.)

About the Google Cloud Storage (GCS) client library

The GCS client library lets your application read files from and write files to buckets in Google Cloud Storage (GCS). This library supports reading and writing large amounts of data to GCS, with internal error handling and retries, so you don’t have to write your own code to do this. Moreover, it provides read buffering with prefetch so your app can be more efficient.

The GCS client library includes the following functionality:

Where to download the GCS client library

For download instructions and distribution contents, see the downloads page.

What you need to do to use the GCS client library

In order to access GCS from App Engine, you must activate a Cloud project for GCS as described on the activation page.

Alternative methods for accessing Google Cloud Storage

The GCS client library provides a way to read from and write to Google Cloud Storage that is closely integrated with Google App Engine, enabling App Engine apps to create objects in GCS and serve them from GCS.

However, there are other ways to access GCS from App Engine besides using the GCS client library. You can use any of these methods as well:

Blobstore API

You can use the Blobstore API to upload objects to and serve objects from GCS using the BlobStore API. You’ll need to use theBlobstoreService.createGsBlobKey() method to create a blob key representing the GCS object. This approach is useful for uploading files from a web page. When the Blobstore API is used together with the Images API, you get a powerful way to serve images, because you can serve images directly from GCS, bypassing the App Engine app, which saves on instance hour costs.

GCS REST API

You can use the Cloud Storage REST API directly to read and write data to GCS. The GCS client library actually uses the Cloud Storage REST API. However, the GCS REST API lacks the App Engine optimizations already done for you by the GCS client library, so you may be doing unnecessary work if you use the GCS REST API directly. If the GCS client library lacks some feature you need, and the REST API supplies that feature, using the REST API may be a good option.

GCS storage manager

If you need to upload objects quickly and don’t mind a manual process, you can use the GCS Storage Manager.

Key concepts of Google Cloud Storage

For complete details on GCS, incuding a complete description of concepts, you need to refer to the GCS documentation. The following brief synopsis of some GCS features impacting the GCS client library are provided as a convenience.

Buckets, objects, and ACLs

The storage location you read files from and write files to is a GCS bucket. GCS client library calls always specify the bucket being used. Your project can access multiple buckets. How do these buckets get created? There are no client library calls currently for creating GCS buckets, so you need to create these upfront using the Google Storage Manager or the gsutil tool provided by GCS.

Access to the buckets and to the objects contained in them is controlled by an access control list (ACL). Your Google Cloud project and your App Engine app are added to the ACL permitting bucket access during activation. The ACL governing bucket access is distinct from the potentially many ACLs governing the objects in that bucket. Thus, your app has read and write priviledges to the bucket(s) it is activated for, but it only has full rights to the objects it creates in the bucket. Your app’s access to objects created by other apps or persons is limited to the rights given your app by the objects’ creator.

If an object is created in the bucket without an ACL explicitly defined for it, it uses whatever default object ACL has been assigned to the bucket by the bucket owner. If the bucket owner has not specified a default object ACL, the object default is public-read, which means that anyone allowed bucket access can read the object.

ACLs and the GCS Client Library

An app using the GCS client library cannot change the bucket ACL, but it can specify an ACL that controls access to the objects it creates. The available ACL settings are described under documentation for the GcsService.FcsFileOptions object.

Modifying GCS objects

Once you have created an object in a bucket, it cannot be modified (no appending). To modify an object in a bucket, you need to overwrite the object with a new object of the same name that contains your desired changes.

GCS and “subdirectories”

Google Cloud Storage documentation refers to “subdirectories” and the GCS client library allows you to supply subdirectory delimiters when you create an object. However, GCS does not actually store the objects into any real subdirectory. Instead, the subdirectories are simply part of the object filename. For example, if I have a bucket my_bucket and store the file somewhere/over/the/rainbow.mp3, the file rainbow.mp3 is not really stored in the subdirectory somewhere/over/the/. It is actually a file named somewhere/over/the/rainbow.mp3.

Retries and exponential backoff

The GCS client library provides a configurable mechanism for automatic request retries in event of timeout failures when accessing GCS. The same mechanism also provides exponential backoff to determine an optimal processing rate. (For a description of exponential backoff in GCS, see the Google Cloud Storage documentation on backoff.)

To change the default values for retries and backoff, you use the RetryParams class.

Using GCS client library with the development app server

You can use the client library with the development server from SDK version 1.8.1 and greater. This provides GCS emulation using the local disk.

Pricing, quotas, and limits

There are no charges associated with making GCS client library calls to Google Cloud Storage.

However, any data stored at GCS is charged the usual GCS data storage fees. Cloud Storage is a pay-to-use service; you will be charged according to the Cloud Storage price sheet.

What to do next

To create, deploy, and run your app:

  1. Download the client library.
  2. Create an App Engine project and activate it for GCS.
  3. Optionally, if you have an existing app that uses the older Google Cloud Storage API, migrate your app.
  4. Go through the brief Getting Started instructions for a quick orientation in using the library.
  5. Upload and deploy your app to production App Engine.
  6. Test the app for expected behavior with GCS.

AngularJS: Yeoman

[Fuente : http://yeoman.io/]

YEOMAN 1.0

Introducción

Yeoman 1.0 es más que una herramienta. Es un workflow; una colección de herramientas y mejores prácticas para trabajar mejor cuando se programa web.

Nuestro workflow se compone de tres herramientas que mejoran tu productividad y satisfacción a la hora de desarrollar una web app:

  • Yo : el andamiaje de la nueva aplicación,  genera la configuración Grunt y tareas Grunt usuales que podrías necesitar para hacer los builds.
  • Grunt se utiliza para hacer los builds , previsualizar y probar tu proyecto.
  • Bower se utiliza para gestión de dependencias, de forma que nunca más tengas que manualmente descargarte y referenciar las librerias de javascript.

Estas  tres herramientas son programadas y mantenidas de forma separada , pero funcionan bien juntas como partes de un workflow efectivo.

Instalación

yo

Yo es mantenido por el proyecto Yeoman y ofrece el esqueleto de una aplicación web, utilizando templates a los que nos refereriremos como generadores. Tipicamente se instala yo y cualquier generador que creas que puedas usar utilizando npm.

Instalando yo y algunos generadores

Lo primero , necesitas instalar yo y otras herramientas necesarias:

npm install -g yo

If you are using npm 1.2.10 or above, this will also automatically install grunt and bower for you. If you’re on an older version of npm, you will need to install them manually:

# For npm versions < 1.2.10.
npm install -g grunt-cli bower

If you have installed Grunt globally in the past, you will need to remove it first: npm uninstall -g grunt

On Windows, we suggest you use an improved command line tool such as Console2 or PowerShell to improve the experience.

Andamiaje básico

Para hacer el andamiaje de una aplicación web, necesitas instalar el generator-webapp generator:

npm install -g generator-webapp

Este es el generador por defecto de aplicaciones web que te crea el esqueleto de un proyecto conteniendo HTML5 BoilerplatejQueryModernizr, and Bootstrap.Tendrás la elección durante la generación de incluir o no muchos de estos.

Ahora que el generador está instalado , crea un directorio para tu nuevo proyecto y ejecuta:

yo webapp

Cada proyecto que se crea con yo creará también tareas Grunt relevantes que la comunidad cree que son útiles para tu workflow.

El generador webapp se considera la forma más simple de empezar una web app. También proporcionamos framework generators que pueden ser utilizados para hacer el esqueleto de un proyecto con posibles vistas , modelos , controladores y demás.

Ejemplo : Creando el esqueleto de una AngularJS app

Como siempre , antes de utilizar un nuevo generador , asegurate de tener lo último , volviendo a instalarte el web.generator:

npm install -g generator-angular

Después de eso , crea un nuevo directorio para tu applicación , entonces ejecuta:

yo angular

Muchos generadores te permiten personalizar tu app utilizando flags en el comando inicial. Como ejemplo , con generator-angular, puedes poner:

yo angular --minsafe

Con esto estamos generando la estructura de ficheros para una aplicación básica y crea una serie de archivos para una nueva aplicación AngularJS encima de ello. Esto incluye patrones para directivas y controladores asi como esqueletos de Karma unit tests.

Haciendo el esqueleto de los componentes de tu aplicación AngularJS

Algunos generadores pueden ser utilizados para hacer el andamiaje de componentes de tu app – podemos llamarles sub-generadores.

En el framework AngularJS, por ejemplo , tu app se compone de una serie de piezas incluyendo controllers, directives y filtros. Puedes crear el esqueleto de todos estos componentes durante el workflow de desarrollo haciendo lo siguiente:

yo angular:controller myController
yo angular:directive myDirective
yo angular:filter myFilter
yo angular:service myService

Cada generador de framework tiene documentación disponible donde se puede consultar lo que soporta.

Crear tus propios generadores

See Generators.

Bower

Bower es un gestor de paquetes web que te permite fácilmente manejar las dependencias de tus proyectos (como lo que hace Maven con Java). Esto incluye recursos Javascript , imágenes y CSS. Es mantenido por Twitter y la comunidad open-source.

Manejar paquetes utilizando Bower puede ser hecho utilizando los siguientes comandos:

# Search for a dependency in the Bower registry.
bower search <dep>

# Install one or more dependencies.
bower install <dep>..<depN>

# List out the dependencies you have installed for a project.
bower list

# Update a dependency to the latest version available.
bower update <dep>

Using Bower with a project scaffolded using yo

To create a basic web app with a dependency on a jQuery plug-in:

# Scaffold a new application.
yo webapp

# Search Bower's registry for the plug-in we want.
bower search jquery-pjax

# Install it and save it to bower.json
bower install jquery-pjax --save

# If you're using RequireJS...
grunt bower
> Injects your Bower dependencies into your RequireJS configuration.

# If you're not using RequireJS...
grunt bower-install
> Injects your dependencies into your index.html file.

It’s as simple as that.

Your chosen generator may not include the grunt tasks “bower” and “bower-install”. You can read more about how to install and use these atgrunt-bower-requirejs and grunt-bower-install.

Grunt

Grunt es una herramienta de linea de comando para proyectos Javascript. Se puede utilizar para compilar proyectos , pero además tiene otros comandos que puedes utilizar en tu workflow.

Grunt commands

# Preview an app you have generated (with Livereload).
grunt server

# Run the unit tests for an app.
grunt test

# Build an optimized, production-ready version of your app.
grunt

These commands can be used together with the yo binary for a seamless development workflow:

yo webapp
grunt server
grunt test
grunt

AngularJS : NodeJS

[Fuente :

http://nodejs.org/

http://www.ibm.com/developerworks/ssa/opensource/library/os-nodejs/

]

Node.js es una plataforma construida sobre el Chrome’s JavaScript runtime para construir de forma fácil aplicaciones en la red que sean rápidas y escalables.Node.js utiliza un modelo orientado a eventos , no bloqueante del I/O que lo hace muy adecuado para aplicaciones en tiempo real que hacen uso intensivo de datos y que se ejecutan en dispositivos distribuidos.

El objetivo de Node es proporcionar una forma fácil de construir programas en red escalables

En el ejemplo “hola mundo” de web server que se muestra abajo , se pueden manejar muchas conexiones de clientes de forma concurrente. Node le dice al sistema operativo (a través de epoll , kqueue , /dev/poll o select) que debe ser notificado cuando se establezca una nueva conexión, y entonces volver al estado de sleep. Si alguien nuevo se conecta, entonces se ejecuta el callback. Cada conexión ocupa una pequeña pila de memoria.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello Worldn');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

Esto contrasta con el modelo de concurrencia de hoy en día donde se utilizan los hilos del OS. Hacer networking basandose en los hilos del OS (Thread-based) es relativamente ineficiente y muy dificil de utilizar. Vease: this and this.Con Node se maneja la memoria de forma más eficiente cuando hay altas cargas de procesamiento que el sistema que suele reservar 2mb en la pila del thread por cada conexión.

Además, los usuarios de Node son libres de las preocupaciones de dead-locking en el proceso – no hay locks. Casi ninguna función en Node realiza directamente I/O, de forma que el proceso nunca se bloquea. Como no hay bloqueos , programadores no tan expertos pueden realizar desarrollos de forma rápida.

Node es similar en diseño y está influencia por sistema como Ruby’s Event Machine or Python’s Twisted. Node lleva el modelo de eventos un poco más lejos – presenta el loop de eventos como una construcción del lenguaje en vez de como una librería. En otros sistemas there is always a blocking call to start the event-loop. Typically one defines behavior through callbacks at the beginning of a script and at the end starts a server through a blocking call like EventMachine::run(). In Node there is no such start-the-event-loop call. Node simply enters the event loop after executing the input script. Node exits the event loop when there are no more callbacks to perform. This behavior is like browser javascript—the event loop is hidden from the user.

HTTP is a first class protocol in Node. Node’s HTTP library has grown out of the author’s experiences developing and working with web servers. For example, streaming data through most web frameworks is impossible. Node attempts to correct these problems in its HTTP parser and API. Coupled with Node’s purely evented infrastructure, it makes a good foundation for web libraries or frameworks.

But what about multiple-processor concurrency? Aren’t threads necessary to scale programs to multi-core computers? You can start new processes viachild_process.fork() these other processes will be scheduled in parallel. For load balancing incoming connections across multiple processes use the cluster module.

See also:

Un ejemplo : Webserver

This simple web server written in Node responds with “Hello World” for every request.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

To run the server, put the code into a file example.js and execute it with the node program from the command line:

% node example.js
Server running at http://127.0.0.1:1337/

Here is an example of a simple TCP server which listens on port 1337 and echoes whatever you send it:

var net = require('net');

var server = net.createServer(function (socket) {
  socket.write('Echo serverrn');
  socket.pipe(socket);
});

server.listen(1337, '127.0.0.1');

¿Simplemente qué es Node.js?

Resumen:  Node es un intérprete Javascript del lado del servidor que cambia la noción de cómo debería trabajar un servidor. Su meta es permitir a un programador construir aplicaciones altamente escalables y escribir código que maneje decenas de miles de conexiones simultáneas en una sola máquina física.

Introducción

Si usted ha oído acerca de Node, o si ha leído algún artículo destacando lo increíble que es, tal vez se esté preguntando “¿Simplemente qué es Node.js?”. Tal vez usted todavía tenga preguntas sobre lo que es Node, después de leer su propia página principal. Node definitivamente no es para todos los programadores, pero podría ser la respuesta adecuada para algunos.

Este artículo tratará de responder a los que es Node.js, presentando un breve contexto de los problemas que resuelve, cómo funciona, cómo ejecutar una aplicación simple y, finalmente, dónde Node es una buena solución. No tratará cómo escribir una aplicación Node complicada ni será un tutorial minucioso sobre Node. Leer este artículo le ayudará a decidir si debe continuar aprendiendo sobre Node para utilizarlo en su propio negocio.

¿Qué problema resuelve Node?

La meta número uno declarada de Node es “proporcionar una manera fácil para construir programas de red escalables”. ¿Cuál es el problema con los programas de servidor actuales? Hagamos cuentas. En lenguajes como Java™ y PHP, cada conexión genera un nuevo hilo que potencialmente viene acompañado de 2 MB de memoria. En un sistema que tiene 8 GB de RAM, esto da un número máximo teórico de conexiones concurrentes de cerca de 4.000 usuarios. A medida que crece su base de clientes, si usted desea que su aplicación soporte más usuarios, necesitará agregar más y más servidores. Desde luego, esto suma en cuanto a los costos de servidor del negocio, a los costos de tráfico, los costos laborales, y más. Además de estos costos están los costos por los problemas técnicos potenciales — un usuario puede estar usando diferentes servidores para cada solicitud, así que cualquier recurso compartido debe almacenarse en todos los servidores. Por todas estas razones, el cuello de botella en toda la arquitectura de aplicación Web (incluyendo el rendimiento del tráfico, la velocidad de procesador y la velocidad de memoria) era el número máximo de conexiones concurrentes que podía manejar un servidor.

Node resuelve este problema cambiando la forma en que se realiza una conexión con el servidor. En lugar de generar un nuevo hilo de OS para cada conexión (y de asignarle la memoria acompañante), cada conexión dispara una ejecución de evento dentro del proceso del motor de Node. Node también afirma que nunca se quedará en punto muerto, porque no se permiten bloqueos y porque no se bloquea directamente para llamados E/S. Node afirma que un servidor que lo ejecute puede soportar decenas de miles de conexiones concurrentes.

Entonces, ahora que usted tiene un programa que puede manejar cientos de miles de conexiones concurrentes, ¿qué puede usted construir en realidad con Node? Sería extraordinario si usted tuviera una aplicación Web que necesitara de toda esta cantidad de conexiones. Ese es uno de esos problemas del tipo “si usted tiene este problema, no es un problema”. Antes de pasar a ello, observemos cómo funciona Node y cómo está diseñado que se ejecute.

Lo que Node definitivamente no es

Sí, Node es un programa de servidor. Sin embargo, el producto base de Node definitivamente No es como Apache o Tomcat. Esos servidores básicamente son productos para servidor listos para instalar y que están listos para implementar aplicaciones instantáneamente. Usted podría tener un servidor estar listo y en operación en un minuto con estos productos. Node definitivamente no es esto. De forma similar a como Apache puede agregar un módulo PHP para permitir a los desarrolladores crear páginas Web dinámicas, y un módulo SSL para conexiones seguras, Node también tiene el concepto de módulos que se pueden agregar a su núcleo mismo. Literalmente hay cientos de módulos de los que se puede escoger con Node, y la comunidad es bastante activa en cuanto a producir, publicar y actualizar docenas de módulos por día. Hablaremos sobre toda la parte de módulos de Node más adelante en este artículo.

Cómo funciona Node

Node ejecuta V8 JavaScript. Espere… ¿qué? ¿JavaScript en el servidor? Sí, leyó correctamente. El JavaScript del lado del servidor puede ser un concepto nuevo para cualquiera que haya trabajado exclusivamente con JavaScript del lado del cliente, pero la idea en sí no es tan inverosímil — ¿por qué no utilizar el mismo lenguaje de programación que usted usa en el cliente del lado del servidor?

¿Qué es el V8? El motor V8 JavaScript es el motor JavaScript subyacente que Google usa con su navegador Chrome. Pocas personas piensan en lo que en realidad sucede con JavaScript en el cliente. Bien, un motor JavaScript en realidad interpreta el código y lo ejecuta. Con el V8, Google creó un intérprete ultra-rápido escrito en C++, con otro aspecto único: usted puede descargar el motor e incorporarlo a cualquier aplicación que desee. No está restringido a ejecutarse en un navegador. Así, Node en realidad usa el motor V8 JavaScript escrito por Google y le da otro propósito para usarlo en el servidor. ¡Perfecto! Para qué crear un nuevo lenguaje cuando ya hay una buena solución disponible.

Programación orientada por eventos

A muchos programadores se les ha hecho creer que la programación orientada a objetos es el diseño perfecto de programación y que no deben usar nada más. Node utiliza lo que se conoce como modelo de programación orientado por eventos.
Listado 1. Programación orientada por eventos del lado del cliente con jQuery

				
// jQuery code on the client-side showing how Event-Driven programming works

// When a button is pressed, an Event occurs - deal with it
// directly right here in an anonymous function, where all the
// necessary variables are present and can be referenced directly
$("#myButton").click(function(){
     if ($("#myTextField").val() != $(this).val())
         alert("Field must match button text");
});

El lado del servidor realmente no es tan diferente del lado del cliente. Es verdad, no se están presionando botones, y no se está ingresando texto en campos, pero a un nivel superior, están sucediendo eventos. Se realiza una conexión — ¡evento! Se reciben datos a través de la conexión — ¡evento! Se dejan de recibir datos por la conexión — ¡evento!

¿Por qué este tipo de configuración es ideal para Node? JavaScript es un gran lenguaje para programación orientada por eventos, porque permite funciones y cierres anónimos, y más importante, la sintaxis es similar para casi cualquier persona que haya codificado. las funciones de devolución de llamado que se llaman cuando ocurre un evento pueden escribirse en el mismo punto en el que usted captura el evento. Fácil de codificar, fácil de mantener. No hay infraestructuras complicadas Orientadas a Objeto, no hay interfaces, no hay potencial para sobre-arquitectura de nada. Simplemente esperar por un evento, escribir una función de devolución de llamado, ¡y se ha resuelto todo!

Aplicación Node de ejemplo

¡Finalmente vamos a ver algo de código! Reunamos todas las cosas sobre las que hemos tratado y creemos nuestra primera aplicación Node. Como hemos visto que Node es ideal para el manejo de aplicaciones de alto tráfico, creemos una aplicación Web bastante simple, construida para máxima velocidad. Estas son las especificaciones para nuestra aplicación de muestra pasadas por el “jefe”: Cree una API RESTful generadora de números aleatorios. La aplicación debe recibir una entrada, un parámetro llamado “number”. La aplicación retornará un número aleatorio que esté entre 0 y este parámetro, y retornará ese número generado a quien hizo el llamado. Y, como el “jefe” espera que esta sea una aplicación masivamente popular, deberá manejar 50.000 usuarios concurrentes. Observemos el código:
Listado 2. Generador Node de números aleatorios

				
// these modules need to be imported in order to use them.
// Node has several modules.  They are like any #include
// or import statement in other languages
var http = require("http");
var url = require("url");

// The most important line in any Node file.  This function
// does the actual process of creating the server.  Technically,
// Node tells the underlying operating system that whenever a
// connection is made, this particular callback function should be
// executed.  Since we're creating a web service with REST API,
// we want an HTTP server, which requires the http variable
// we created in the lines above.
// Finally, you can see that the callback method receives a 'request'
// and 'response' object automatically.  This should be familiar
// to any PHP or Java programmer.
http.createServer(function(request, response) {

     // The response needs to handle all the headers, and the return codes
     // These types of things are handled automatically in server programs
     // like Apache and Tomcat, but Node requires everything to be done yourself
     response.writeHead(200, {"Content-Type": "text/plain"});

     // Here is some unique-looking code.  This is how Node retrives
     // parameters passed in from client requests.  The url module
     // handles all these functions.  The parse function
     // deconstructs the URL, and places the query key-values in the
     // query object.  We can find the value for the "number" key
     // by referencing it directly - the beauty of JavaScript.
     var params = url.parse(request.url, true).query;
     var input = params.number;

     // These are the generic JavaScript methods that will create
     // our random number that gets passed back to the caller
     var numInput = new Number(input);
     var numOutput = new Number(Math.random() * numInput).toFixed(0);

     // Write the random number to response
     response.write(numOutput);

     // Node requires us to explicitly end this connection.  This is because
     // Node allows you to keep a connection open and pass data back and forth,
     // though that advanced topic isn't discussed in this article.
     response.end();

   // When we create the server, we have to explicitly connect the HTTP server to
   // a port.  Standard HTTP port is 80, so we'll connect it to that one.
}).listen(80);

// Output a String to the console once the server starts up, letting us know everything
// starts up correctly
console.log("Random Number Generator Running...");

Iniciando esta aplicación

Ponga el código anterior en un archivo llamado “random.js”. Ahora, para comenzar esta aplicación y ejecutarla (creando así el servidor HTTP y escuchando las conexiones en el puerto 80), simplemente corra el siguiente comando en su prompt de comandos: % node random.js. Así es como se verá cuando usted sepa que el servidor estará listo y en funcionamiento.

root@ubuntu:/home/moila/ws/mike# node random.js
Random Number Generator Running...

Accediendo a la aplicación

La aplicación está lista y funcionando. Node está escuchando a cualquier conexión en este momento, así que vamos a probar la aplicación. Como hemos creado una API RESTful simple, podemos accesar a la aplicación usando nuestro navegador Web. Digite la siguiente dirección (asegúrese de haber completado el paso anterior),

http://localhost/?number=27

La ventana de su navegador cambiará a un número aleatorio entre 0 y 27. Presione recargar en su navegador y obtendrá otro número aleatorio. Listo, ¡esta es su primera aplicación Node!

Node, ¿para qué sirve?

Entonces, después de leer todo sobre Node, usted tal vez pueda responder la pregunta “Simplemente qué es Node?” pero usted puede quedar con la duda sobre “¿En qué puedo utilizar Node?” Esa es una pregunta importante ya que hay algunas cosas para las que Node es realmente bueno.

Para qué sirve

Como ha visto hasta ahora, Node está extremadamente bien diseñado para situaciones en que usted esté esperando una gran cantidad de tráfico y donde la lógica del lado del servidor y el procesamiento requeridos, no sean necesariamente grandes antes de responder al cliente. Aquí hay algunos buenos ejemplos en donde Node haría un gran trabajo:

  • Una API RESTfulUn servicio Web que proporcione una API RESTful toma algunos parámetros, los interpreta, arma una respuesta y descarga esa respuesta (usualmente una cantidad relativamente pequeña de texto) de vuelta al usuario. Esta es una situación ideal para Node, porque puede construirse para que maneje decenas de miles de conexiones. Tampoco requiere una gran cantidad de lógica y básicamente sólo busca valores de una base de datos y los reúne como una respuesta. Como la respuesta es una pequeña cantidad de texto y la solicitud entrante es una pequeña cantidad de texto, el volumen de tráfico no es alto, y una máquina probablemente puede manejar las demandas de API de incluso la API de la más ocupada de las empresas.
  • Fila de TwitterPiense en una compañía como Twitter que recibe tweets y los escribe en una base de datos. Literalmente hay miles de tweets llegando cada segundo y la base de datos posiblemente no puede seguir el ritmo del número de escrituras necesarias durante los horarios pico de uso. Node se convierte en una pieza clave de la solución a este problema. Como hemos visto, Node puede manejar decenas de miles de tweets entrantes. Luego puede escribirlos rápida/fácilmente en un mecanismo de cola en memoria (memcached, por ejemplo), desde donde otro proceso separado puede escribirlos en la base de datos. El rol de Node en esto es reunir rápidamente el tweet y pasar esta información hacia otro proceso responsable de escribirlo. Imagine otro diseño — un servidor PHP normal que intente manejar escrituras en la base de datos misma — cada tweet podría causar una pequeña demora mientras se escribe en la base de datos, dado que el llamado de base de datos estaría bloqueando. Una máquina con este diseño sólo podría manejar 2.000 tweets entrantes por segundo, debido a la latencia de base de datos. A un millón de tweets por segundo, usted estaría hablando de 500 servidores. Node, en cambio, maneja cada conexión y no causa bloqueo, permitiéndole capturar tantos tweets como se le puedan arrojar. Una máquina nodo capaz de manejar 50.000 tweets por segundo, y usted estaría hablando de sólo 20 servidores.
  • Estadísticas de videojuegosSi usted alguna vez jugó un juego como Call of Duty on-line, algunas cosas le habrán llamado la atención inmediatamente cuando observó las estadísticas del juego, principalmente el hecho de que deben estar rastreando toneladas de información sobre el juego para poder producir tal nivel de estadísticas. Luego, multiplique esto por los millones de personas que lo juegan en cualquier momento, y tendrá una idea de la inmensa cantidad de información que se genera con bastante rapidez. Node es una buena solución para este escenario, porque puede capturar los datos que están generando los juegos, hacer un mínimo de consolidación con ellos y luego ponerlos en una fila para escribirlos en una base de datos. Parecería algo tonto dedicar todo un servidor a rastrear cuántas balas disparan las personas en los juegos, lo cual podría ser el límite útil si usted utilizara un servidor como Apache, pero parecería menos tonto si en lugar de ello usted pudiera dedicar un solo servidor a rastrear casi todas las estadísticas de un juego, como usted puede llegar a hacerlo con un servidor que ejecute Node.
Módulos Node

Aunque originalmente no era un tema planeado en el artículo, debido a la demanda popular, el artículo se ha expandido para incluir una breve introducción a los Node Modules y al Node Package Manager. Así como a lo que las personas se han acostumbrado al trabajar con Apache, usted puede expandir la funcionalidad de Node instalando módulos. No obstante, los módulos que usted puede utilizar con Node mejoran en gran medida el producto, tanto, que es poco probable que haya alguien que utilice Node sin instalar por lo menos algunos módulos. Así de importantes se han tornado los módulos, hasta el punto de convertirse en parte esencial del producto completo.

En el aparte de Recursos, incluyo un enlace a la página de módulos, donde están listados y disponibles todos los módulos posibles. Como una muestra rápida de las posibilidades, estos incluyen un módulo para escribir páginas creadas dinámicamente (como PHP), un módulo para facilitar el trabajo con MySQL, un módulo para ayudar con WebSockets, y un módulo para asistir en el análisis de texto y de parámetros, entre docenas de módulos disponibles. No entraré en detalles sobre los módulos, porque como mencioné, este sólo es un artículo de visión general que le ayuda a entender si Node es algo que usted debería buscar más adelante, pero es posible, si decide utilizarlo más adelante, que definitivamente también vaya a trabajar con los módulos disponibles.

Adicionalmente, Node presenta el Node Package Module, que es una forma integrada de instalar y administrar los módulos Node que esté usando. Este maneja automáticamente dependencias, de manera que usted puede estar seguro(a) de que cualquier módulo que usted desee instalar se instalará correctamente con todas sus partes necesarias. También sirve como una forma para publicar sus propios módulos en la comunidad Node, si usted opta por vincularse y escribir su propio módulo. Piense en el NPM como una forma fácil para expandir la funcionalidad de Node sin tener que preocuparse por desconfigurar su instalación Node. De nuevo, si usted opta por continuar avanzando en Node, el NPM será parte vital de su solución Node.

Nota del Editor

La versión inicialmente publicada de este artículo generó bastantes comentarios por parte de la comunidad, sobre los diferentes puntos que se presentaron. Desde ese entonces el autor ha revisado este artículo con esas ideas en mente. Este tipo de revisión y discusión por lo pares es parte vital del mundo de fuente abierta. Gracias a aquellos(as) que aportaron sus comentarios constructivos.

Como todos los proyectos de fuente abierta, Node.js continuará evolucionando y los desarrolladores descubrirán nuevos recursos y técnicas para superar cualquier número de limitaciones. Como siempre, alentamos a nuestros usuarios a que prueben la tecnología por sí mismos.

La pregunta que muchos de ustedes tenían al comienzo de este artículo “¿Simplemente qué es Node.js?” debería quedar respondida después de leerlo. Usted debe poder explicar en unas pocas frases sencillas y concisas lo que es Node.js. Si usted puede hacerlo, entonces estará un paso adelante de casi cualquier otro programador. Muchas personas con las que he hablado sobre Node han estado confundidas con respecto a lo que hace exactamente. Ellas están, y es comprensible, pensando en modo Apache — (— un servidor es una aplicación en la que usted descarga sus archivos HTML y todo funciona). Como la mayoría de los programadores están acostumbrados a Apache y a lo que hace, la forma más fácil de describir Node es comparándolo con Apache. Node es un programa que puede hacer todo lo que hace Apache (con algunos módulos), pero que también puede hacer mucho más, al ser una plataforma JavaScript extensible desde la cual usted puede construir.

En este artículo usted ha visto cómo Node cumple con sus metas de proporcionar servidores altamente escalables. Utiliza un motor JavaScript extremadamente rápido de Google, el motor V8. Utiliza un diseño Orientado por Eventos para mantener el código al mínimo y fácil de leer. Todos estos factores conducen a la meta deseada por Node — es relativamente fácil escribir una solución masivamente escalable.

Tan importante como entender lo que Node es, también es importante entender lo que Node no es. Node no es simplemente un reemplazo de Apache que instantáneamente vaya a hacer más escalable su aplicación Web PHP. Eso no podría estar más lejos de la verdad. Todavía es muy temprano en la vida de Node, pero está creciendo extremadamente rápido, la comunidad está involucrada muy activamente, se está creando una gran cantidad de módulos, y este producto en crecimiento podría estar en su negocio dentro de un año.

df
dfd
fd
fd
fdf
df
df
df
df
df
df
dfd
fd
fd
fd

Angular JS Book: Chapter 3: Organización de proyecto

[Fuente: Angular JS Ebook Chapter 3]

Te recomendamos iniciar tu proyecto con Yeoman, con el que te creas la estructura básica para iniciar una aplicación AngularJS.

Los ficheros de una aplicación se pueden clasificar en las siguientes categorías:

Ficheros fuente JS

Take a look at the app/scripts folder. This is where all your JS source code lives. One main file (app/scripts/app.js) will set up the the Angular module and the routes for your application.

In addition, there is a separate folder—app/scripts/controller—which houses the individual controllers. Controllers provide the action and publish data to the scope which will then be displayed in the view. Usually, they correspond one to one with the view.

Directives, filters, and services can also be found under app/scripts, either as complete files (directives.js, filters.js, services.js), or individually, if they are nice and complex.

HTML Angular template files

Now, every AngularJS partial template that Yeoman creates can be found in the app/views folder. This will mirror our app/scripts/controller folder for the most part.

There is one other important Angular template file, which is the main app/index.html. This is responsible for sourcing the AngularJS source files, as well as any source files you create for your application.If you end up creating a new JS file, ensure that you add it to the index.html, and also update the main module and the routes (Yeoman does this for you as well!).

JS library dependencies

Yeoman provides you the app/scripts/vendor folder for all JS source dependencies.Want to use Underscore or SocketIO in your application? No problem—add the dependency to the vendor folder (and your index.html!) and start referencing it in your application.

Static resources

You are creating an HTML application in the end, and it is a given that you will have CSS and image dependencies that you need served as part of your application.

The app/styles and app/img folders are for this very purpose. Just add what you need and start referring to them (with the correct relative paths, of course!) in your application.

Yeoman does not create the app/img path by default.

Unit tests

Testing is super important, and totally effortless when it comes to AngularJS. The
test/spec folder should mirror your app/scripts in terms of tests. Each file should
have a mirror spec file which has its unit tests. The seed creates a stub for each
controller file, under test/spec/controllers, with the same name as the original controller.
These are Jasmine-style specs, which describe a specification for each expected
behavior of the controller.

Integration tests

AngularJS comes with end-to-end testing support built right into the library. All
your E2E tests, in the form of Jasmine specs, are saved under the folder tests/e2e.
Yeoman does not create the tests/folder by default.

While the E2E tests might look like Jasmine, they are not. They are
functions that are executed asynchronously, in the future, by the
Angular Scenario Runner. So don’t expect to be able to do stuff like
you would in a normal Jasmine test (like console.log on the value
of a repeater).

There is also a simple HTML file generated that can be opened by itself in a browser
to run the tests manually. Yeoman doesn’t generate the stubs for these yet, but they
follow a similar style to the unit tests.

Configuration files

There are two configuration files needed. The first one, karma.conf.js, is generated
by Yeoman for you and is used to run the unit tests.

The second one, which Yeoman does not generate yet, is the karma.e2e.conf.js. This is used to run the scenario tests.

There is a sample file at the end of this chapter in the RequireJS integration section.
The config details the dependencies and the files to use when running the unit tests
using Karma. By default, it runs the Karma server at port 9876.

You might ask: how do I run my application? What about unit tests? How do I even
write these various pieces that you are talking about?

Don’t worry, young grasshopper, all in due time. In this chapter, we will deal with setting
up your project and development environment so that things can move along at a rapid
pace once we do start churning out some awesome code. What code you write, and how
it hooks together to form your final awesome application, will come in the next few
chapters.

Testing with AngularJS

We have said it before (even right in this chapter), and we will say it again: testing is
essential, and AngularJS makes it simple to write the right kind of unit and integration
tests. While AngularJS plays nicely with multiple test runners, we strongly believe that
Karma trumps most of them providing the most robust, solid, and insanely fast test
runner for all your needs.

Karma

Karma’s main reason for existence is to make your test-driven development (TDD)
workflow simple, fast, and fun. It uses NodeJS and SocketIO (you don’t need to know
what they are, just assume that they are awesome, cool libraries) to allow running your code, and tests in multiple browsers at insanely fast speeds. Go find out more at https://github.com/vojtajina/karma/.

TDD: An Intro

Test-driven development, or TDD, is an AGILE methodology that flips the development
lifecycle by ensuring that tests are written first, before the code is implemented, and that
tests drive the development (and are not just used as a validation tool).
The tenets of TDD are simple:

  • Code is written only when there is a failing test that requires the code to pass
  • The bare minimum amount of code is written to ensure that the test passes
  • Duplication is removed at every step
  • Once all tests are passing, the next failing test is added for the next required functionality.

These simple rules ensure that:

  • Your code develops organically, and that every line of code written is purposeful.
  • Your code remains highly modular, cohesive, and reusable (as you need to be able to test it).
  • You provide a comprehensive array of tests to prevent future breakages and bugs.
  • The tests also act as specification, and thus documentation, for future needs and changes.

We at AngularJS have found this to be true, and the entire AngularJS codebase has been developed using TDD. For an uncompiled, dynamic language like JavaScript, we strongly believe that having a good set of unit tests will reduce headaches in the future!
So how do we get this awesomeness that is Karma? Well, first ensure that NodeJS is
installed on your machine. This comes with NPM (Node Package Manager), which
makes it easy to manage and install the thousands of libraries available for NodeJS.
Once you have NodeJS and NPM installed, installing Karma is as easy as running:

sudo npm install -g karma

There you go. You are ready to start Karmaing (I just made that up, please don’t go about using it in real life) in three easy steps!

Getting your config file up

If you used Yeoman to create your app skeleton, then you already have a readymade
Karma config file waiting for you to use. If not, just go ahead and execute the
following command from the base folder of your application directory:

karma init

in your terminal console, and it will generate a dummy config file (karma.conf.js)
for you to edit to your liking, with some pretty standard defaults. You can use that.

Starting the Karma server

Just run the following command:

karma start [optionalPathToConfigFile]

This will start the Karma server on port 9876 (the default, which you can change
by editing the karma.conf.js file from the previous step). While Karma should open
up a browser and capture it automatically, it will print all the instructions needed
to capture another browser in the console. If you are too lazy to do that, just go to
http://localhost:9876 in another browser or device, and you are good to start running
tests in multiple browsers.While Karma can capture the usual browsers automatically, on start (Firefox, Chrome, IE, Opera, and even PhantomJS), it is not limited to just those browsers. Any device on which you can browse to a URL can possibly be a runner for Karma. So if you open up the browser of your iPhone or Android device and browse to http://machinename:9876 (provided it is accessible!), you could potentially run your tests on mobile devices as well.

Running the tests

Execute the following command:

karma run

That’s it. You should get your results printed right in the console where you ran the
command. Easy, isn’t it?
Unit Tests

AngularJS makes it easy to write your unit tests, and supports the Jasmine style of writing tests by default (as does Karma). Jasmine is what we call a behavior-driven development framework, which allows you to write specifications that denote how your code should behave. A sample test in Jasmine might look something like this.

describe("MyController:", function() {
	it("to work correctly", function() {
		var a = 12;
		var b = a;
		expect(a).toBe(b);
		expect(a).not.toBe(null);
	});
});

As you can see, it lends itself to a very readable format, as most of the code that could
be read in plain English. It also provides a very diverse and powerful set of matchers
(like the expect clauses), and of course has the xUnit staples of setUp and tearDowns
(functions that are executed before and after each individual test case).

AngularJS provides some nice mockups, as well as testing functions, to allow you to
create services, controllers, and filters right in your unit tests, as well as mock out
HttpRequests and the like. We will cover this in Chapter 5.

Karma can be integrated with your development workflow to make it easier, as well as
to get faster feedback on the code you have written.

Integration with IDEs
Karma does not have plug-ins (yet!) for all the latest and greatest IDEs, but you
don’t really need any. All you need to do is add a shortcut command to execute
“karma start” and “karma run” from within your IDE. This can usually be done by
adding a simple script to execute, or the actual shell command, depending on your
choice of editor. You should see the results every time it finishes running, of course.

Running tests on every change
This is utopia for many TDD developers: being able to run all their tests, every time
they press save, within a few milliseconds, and get results back quickly. And this
can be done with AngularJS + Karma pretty easily. Turns out, the Karma config file
(remember the karma.conf.js file from before?) has an innocuous-looking flag
named “autoWatch”. Setting it to true tells Karma to run your tests every time the
file it watches (which is your source and test code) changes. And if you do “karma
start” from within your IDE, guess what? The results from the Karma run will be
available right within your IDE. You won’t even need to switch to console or terminal
to figure out what broke!

d
s
sd
sd
sds
ds
dsd
sd
sd
sd
ds
d
ds
ds
ds
dd
sd
sds

AngularJS Book: Chapter 2: Guía rápida de Angular

[Fuente: AngularJS Book –  www.it-ebooks.info E:DOCSDEVANGULARJSig103_14AngularJS]

[Ejemplos en pruebas/workspace/angularjs-test]

Invocando Angular

Todas las aplicaciones que quieran utilizas Angular deben hacer dos cosas:

  • Referenciar la libreria angular.js
  • Decirle a Angular qué parte del DOM debe gestionar con la directiva ng-app

Referenciando la librería angular

  • Es mejor utilizar un CDN para que los usuarios puedan cachear esta librería cuando se usa en varias apps.
  • El CDN de Google:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

Declarando el ámbito de funcionamiento de angular con ng-app

  • Si queremos que Angular maneje todo el DOM:
<html ng-app>
---
</html>
  • Si tienes que meter Angular en una aplicación existente donde hay ya otra tecnología que maneja el DOM, podemos declarar que Angular sólo maneje parte de la página colocando la directiva ng-app en un un elemento div de la página:
<html>
...
<div ng-app>
...
</div>
...
</html>

Modelo Vista Controlador

  • AngularJS soporta el estilo de Modelo-Vista-Controlador en el diseño de las aplicaciones
  • Por tanto lo mejor es adaptar el diseño de las apps a este modelo donde siempre encontraremos lo siguiente:
    • Un modelo conteniendo los datos que representan el estado actual de tu aplicación
    • Vistas que muestran esos datos
    • Controladores que manejan las relaciones entre tu modelo y tus vistas
  • El modelo se crea utilizando atributos de objeto , o incluso tipos primitivos conteniendo los datos. Por ejemplo si queremos pintar un texto al usuario , podríamos tener una cadena como la siguiente:
var someTexr = 'hola caracola';
  • Para crear tus vistas es tan simple como crear páginas HTML que se fusionarán con tu modelo. Dentro del HTML podemos invocar a datos del modelo con las  dobles llaves:
<p>{{someText}}</p>
  • Los controladores son clases o tipos que se hacen para decirle a Angular qué objetos o primitivas son los que forman parte de tu modelo.Esto se hace asignando los mismos al objeto $scope pasado como parámetro del controlador:
function TextController ($scope) {
  $scope.someText = someText;
}
  • Poniendolo todo junto tenemos
<html ng-app>
<body ng-controller="TextController">
	<p>{{someText}}</p>

	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

	<script>
		function TextController ($scope) {
		  $scope.someText = "Hola caracola";
		}
	</script>

</body>
</html>

Cargando esta página en un navegador , veremos:

Hola caracola
  • Aunque esta forma de definir el modelo  , al estilo tipo primitivo , es válida, para la mayoría de las aplicaciones es mejor crear un objeto modelo que sirva de contenedor. Asi , por ejemplo , las variables de modelo del ejemplo anterior podrían ser asi:
var messages = {};
messages.someText = 'Hola caracola';
function TextController ($scope) {
	$scope.messages = messages;
}

y en la plantilla invocamos al modelo de la siguiente forma:

<p>{{messages.someText}}</p>
  • Como veremos más adelante , cuando hablemos del objecto $scope , crear el modelo de esta forma previene de comportamiento inesperado causado por la herencia de prototipos en los objetos $scope.
  • Sobre el controlador , también añadir , que aunque en el ejemplo hemos incluido el TextController en el ámbito global, la forma correcta de definir un controlador es como parte de lo que llamaremos un “módulo” , lo cual proporciona un namespace para partes relacionadas de nuestra app. Con un módulo el ejemplo quedaría así:
<html ng-app = 'myApp'>
<body ng-controller="TextController">
<p>{{messages.someText}}</p>

	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

	<script>
		var myAppModule = angular.module('myApp',[]);
		myAppModule.controller('TextController',
			function ($scope) {
				var messages = {};
				messages.someText = 'Hola caracola';
				$scope.messages = messages;
			}
		);
	</script>

</body>
</html>
  • Más adelante explicaremos los porques y los comos de trabajar con módulos. Por ahora , sólo recuerda que es una buena costumbre mantener las cosas fuera del namespace lgobal y que el mecanismo para hacerlo son los módulos.

Las plantillas (templates) y el data binding

Mostrar texto en las plantillas

  • La forma de mostrar o actualizar texto en las plantillas es utilizando la directiva ng-bind . Esta directiva tiene dos formas equivalentes:
    • Con dobles llaves: <p>{{greeting}}</p>
    • Utilizando la directiva ng-bind: <p ng-bind=”greeting”></p>
  • Las dos formas producen salidas equivalentes, pero hay que decir que en las páginas de entradas a las aplicaciones (index.html) con la sintaxis de las dobles llaves el usuario  , la primera vez de carga del index.html , verá el {{texto}} y con el sintaxis de directiva el usuario no verá nada

Formularios de entradas de datos

  • Trabajar con elementos de formulario en Angular es simple. Como hemos visto en ejemplos anteriores podemos enlazar elementos con el atributo ng-model con atributos del modelo.Esto funciona para todos los tipos de elementos de formulario: text input , radio buttons , checkboxes , etc. Por ejemplo podemos enlazar un checkbox con una property de la siguiente forma:
<form ng-controller="SomeController">
<input type="checkbox" ng-model="youCheckedIt" />
</form>
  • Con este código lo que se hace por detrás es lo siguiente:
    • Cuando el usuario marca la casilla, una property llamada “youCheckedIt” en el $scope del SomeController se pone a true. Si la desmarcamos la pondremos a false.
    • Si ponemos $scope.youCheckedIt a true en el SomeController , entonces la casilla aparecerá marcada en el UI. Y si la ponemos a false aparecerá desmarcada
  • Digamos que ahora queremos realizar algo cuando el usuario cambia algo, En los elementos input podemos utilizar la directiva ng-change para especificar un controlador que debe ser invocado cuando el usuario cambia le valor del input. Por ejemplo , hagamos una simple calculadora para orientar a los emprendedores de cuanto dinero deben invertir:
<form ng-controller="StartUpController">
	Starting: <input ng-change="computeNeeded()" 
	              	 ng-model="funding.startingEstimate">
	Recommmendation: {{funding.needed}}
</form>
  • Como aproximación realista , digamos que calculamos  10 veces la estimación del usuario. Y ponemos un valor de cero por defecto:
function StartUpController($scope) {
	$scope.funding = { startingEstimate: 0};
	$scope.computeNeeded = function() {
		$scope.funding.needed = $scope.funding.startingEstimate * 10;
	};
}
  •  Hay un problema potencial con esta estrategía: el valor estimado se recalcula sólo cuando el usuario escribe alguna cantidad en la caja de texto. Pero, ¿qué pasa si el dato recalculado debe cambiar dependiendo de datos que vienen del servidor?
  • Para actualizar un campo sin importar cómo, podemos utilizar una función del $scope llamada $watch:
function StartUpController($scope) {
	$scope.funding = { startingEstimate: 0};
	$scope.computeNeeded = function() {
		$scope.needed = $scope.funding.startingEstimate * 10;
	};

	$scope.$watch('funding.startingEstimate',  computeNeeded);
}
  • Entonces podemos reescribir el template de la siguiente forma:
<form ng-controller="StartUpController">
	Starting: <input  ng-model="funding.startingEstimate">
	Recommmendation: {{funding.needed}}
</form>
  • Habrá casos donde no quieres que se hagan acciones en cada cambio , sino que quieres esperar hasta que el usuario diga que se actualice. Por ejemplo al completar un compra o enviar un mensaje de chat.
  • Hay una forma de agrupar los inputs , con la directiva ng-input que especifique la función a llamar cuando se haga submit en el formulario. Asi , en el ejemplo anterior , podemos hacer que se recalcule la estimación cuando el usuario haga click en un botón:
<form ng-submit="requestFunding()" ng-controller="StartUpController">
	Starting: <input ng-change="computeNeeded()" ng-model="funding.startingEstimate">
	Recommmendation: {{funding.needed}}
	<button>Fund my startup!</button>
</form>

function StartUpController($scope) {
	$scope.funding = { startingEstimate: 0};
	$scope.computeNeeded = function() {
		$scope.needed = $scope.funding.startingEstimate * 10;
	};

	$scope.requestFunding = function() {
		window.later("Sorry , please get more customers first.");
	}

	$watch('funding.startingEstimate',  computeNeeded);
}
  • La directiva ng-submit previene automáticamente de que se produzca el POST por defecto cuando se intenta hacer submit del formulario.
  • Se pueden manejar otros eventos con directivas de angular. Por ejemplo para el onclick tenemos la directiva ng-click , para ondblClick , tenemos la bg-dblClick, y asi. Como ejemplo podemos añadir un botón de reset al formulario de nuestro ejemplo:
<form ng-submit="requestFunding()" ng-controller="StartUpController">
	Starting: <input ng-change="computeNeeded()" ng-model="funding.startingEstimate">
	Recommmendation: {{funding.needed}}
	<button>Fund my startup!</button>
	<button ng-click="reset()">Reset</button>
</form>

function StartUpController($scope) {
	$scope.funding = { startingEstimate: 0};
	$scope.computeNeeded = function() {
		$scope.needed = $scope.funding.startingEstimate * 10;
	};

	$scope.requestFunding = function() {
		window.later("Sorry , please get more customers first.");
	}

	$watch('funding.startingEstimate',  computeNeeded);

	$scope.reset = function() {
		$scope.funding.startingEstimate = 0;	
	}

}

Listas,  Tablas y otros elementos de repetición

  • Ejemplo 1: Uso de directiva ng-repeat Queremos mostrar una lista de estudiantes con datos que vienen desde el servidor. Haremos un ejemplo simulando la lista de estudiantes en una variable de modelo:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html ng-app>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
		<title>AngularJS Test : Student list</title>
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
	</head>
	<body ng-controller='StudentController'>
		<h1>Student List</h1>
		<ul >
			<li ng-repeat='student in students'>
				<a href='/student/view/{{student.id}}'>{{student.name}}</a>
			</li>			
		</ul>
		<button ng-click="insertStudent('Potitorrrr')">Insert Student</button>

		<script>
		function StudentController($scope) {
			$scope.students = [
			                {name: 'Manzanas' , id:'1'},
			                {name: 'Manzanas 2' , id:'2'},
			                {name: 'Manzanas 3' , id:'3'},
			                ];
			$scope.insertStudent = function(name) {
				$scope.students.splice(1,0,{name: name , id:'4'});
			}
		}
		</script>
	</body>
</html>
  • Ejemplo 2: Bucle reeferenciando el índice del elemento en curso con $index. También existen booleanos de angular que te dicen si estás en el primero ($first) , en algún punto en el medio ($middle) o en el último ($last). Siguiendo con nuestro ejemplo vamos a etiquetar los registros de estudiantes con un índice:
		<ul >
			<li ng-repeat='student in students'>
				<span>{{$index + 1}}</span> <a href='/student/view/{{student.id}}'>{{student.name}}</a>
			</li>			
		</ul>

Algunas notas sobre Javascript no obstrusivo

  • En algún momento como programador Javascript  ,alguién igual te dijo que deberías escribir “Javascript no obstrusivo” , y que utilizar event handlers en los click , mousedown dentro del HTML era una mala idea. Pues tenían razón.
  • La idea de Javascript no obstrusivo ha sido interpretado de muchas formas, pero la versión más lógica sigue las siguientes normas:
    • No todos los navegadores soportan Javascript.Permite que todo el mundo pueda ver tu contenido o usar tu app sin la necesidad de ejecutar código en el navegador.
    • Algunos utilizan navegadores que trabajan de forma diferente. Algunos invidentes utilizan screen-readers y algunos usuarios de mobiles no pueden visualizar webs que tengan Javascript.
    • Javascript funciona de forma diferente según las plataformas. IE es el campeón. Hay que añadir código diferente de event-handling según el navegador.
    •  Los event handlers hacen referencia a funciones en el global namespace. Puede causarte dolores de cabeza cuando intentes integrar otras librerías con funciones en el mismo namespace.
    • Los event handlers combinan estructura y comportamiento. Esto hace tu código dificil de mantener , extender y entender.
  • De la mayoría de las formas , la vida fue mejor cuando escribes Javascript en este estilo. Cierto es que se perdió en legibilidad y aumento la complejidad.
  • En vez de declarar tus acciones de event handlers en el elemento sobre el que actua, generalmente tienes que asignar IDs a estos elementos, recuperar la referencia de ese elemento, y configurar event handlers con callbacks
  • En Angular , hemos decidido reexaminar el problema.
  • El mundo ha cambiado desde que estos conceptos nacieron:
    • El punto #1 ya no es cierto para cualquier conjunto de población que haya en el planeta. Si estás ejecutando un navegador sin Javascript , estás limitado a los sites creados en los 90s
    • Sobre el punto #2, los screen-readers modernos han mejorado en ese aspecto. Se pueden hacer UIs buenos siendo a la vez accesibles
    • Los móviles ahora ejecutan Javascript como si fueran ordenadores de sobremesa.
    • Entonces ahora la cuestión es : podemos resolver los puntos #3 y #4 , manteniendo a la vez la legibilidad y simplicidad de la técnica inline
    • Como hemos dicho previamente, para la mayoría inline event handlers, Angular tiene un equivalente en la forma de ng-eventhandler=”expression” donde eventhandler será reemplazado por click , mousedown , change y así.
    • Si quieres ser notificado cuando un usuario hace click sobre un elemento utiliza la directiva ng-click de la siguiente forma:
    • <div ng-click="doSomething()">...</div>
  • Tranquilos , esto no es como el inline html. Las diferencias son:
    • Se comportan de la misma forma en todos los navegadores. Angular se encarga de tratar las diferencias por ti
    • No operan en el global namespace. Las expresiones que especificas con estas directivas pueden sólo acceder a funciones y datos que están en el ámbito del controller del elemento.Este punto es un poco triki , asi que veamos un ejemplo pa ilustrarlo. En una app típica , creamos una nav bar con una content areas que cambia según selecciones una opción del menú en la nav bar. Podríamo escribir el esqueleto para esto como:
  • <div ng-controller="NavController">
     …
     <li ng-click="doSomething()">Something</li>
     …
     </div>
     <div ng-controller="ContentAreaController">
     …
     <div ng-click="doSomething()">...</div>
     …
     </div>

    Aqui tanto los <li> en la navbar como el <div> en la content area invocan una función llamada “doSomething()” cuando el usuario hace click sobre ellos.Como programador, configuras la función a la que van estas llamadas en el código del controlador. Pueden ser funciones con el mismo nombre o diferente:

function NavController($scope) {
 $scope.doSomething = doA;
 }
 function ContentAreaController($scope) {
 $scope.doSomething = doB;
 }
  • Nos queda el punto #5, combinar estructura y comportamiento.Hay una prueba simple para detectar si nuestro sistema sufre de este acoplamiento: ¿podemos crear un test unitario para la lógica de nuestra app que no requiera que el DOM esté presente?. En Angular podemos escribir controllers conteniendo nuestra lógica de negocio sin hacer referencias a el DOM. El problema no estaba en los event handlers, pero sí en la forma en que escribiamos Javascript. Date cuenta que en todos los controladores que hemos visto hasta ahora, en ninguno hay referencias al DOM o a los eventos del DOM en ningún sitio. Todo el trabajo de localizar elementos y manejar eventpos lo hace Angular

Hiding and Showing

  • Para menus , herramientas context-sensitive y en otros muchos casos tenemos que mostrar/ocultar elementos. Con Angular , los cambios UI son manejados desde cambios en el modelo.Tenemos las directivas ng-show y ng-hide
  • Estas directivas funcionan configurando los estilos de los elementos a display:block pare mostrarlos y display:none para esconderlo. Veamos el ejemplo donde queremos montar un panel de control  para Death Ray:
<div ng-controller='DeathrayMenuController'>
<button ng-click='toggleMenu()'>Toggle Menu</button>
<ul ng-show='menuState.show'>
<li ng-click='stun()'>Stun</li>
<li ng-click='disintegrate()'>Disintegrate</li>
<li ng-click='erase()'>Erase from history</li>
</ul>
<div/>
function DeathrayMenuController($scope) {
$scope.menuState.show = false;
$scope.toggleMenu = function() {
$scope.menuState.show = !$scope.menuState.show;
};
// death ray functions left as exercise to reader
}

CSS Classes and Styles

Es obvio que con lo visto hasta ahora se puede dinámicamente configurar clases y estilos de CSS en tu app con tan sólo haciendo un binding con los datos con la notación {{}}.

Se puede incluso componer nombres de clases parciales que se correspondan con los de tu maqueta. Si , por ejemplo , quieres condicionalmente deshabilitar algunos menus , podrías hacer algo como lo siguiente parea visualmente indicárselo al usuario:

Dado el CSS:

.menu-disabled-true {
color: gray;
}

podríamos mostrar la función stun de tu DeathRay como deshabilitada con este código:

<div ng-controller='DeathrayMenuController'>
<ul>
<li class='menu-disabled-{{isDisabled}}' ng-click='stun()'>Stun</li>
...
</ul>
<div/>

donde tu configurarías la propiedad isDisabled a través de tu controlador de la forma apropiada:

function DeathrayMenuController($scope) {
$scope.isDisabled = false;
$scope.stun = function() {
// stun the target, then disable menu to allow regeneration
$scope.isDisabled = 'true';
};
}

Esta técnica funciona igual de bien cuando se combinan inline styles con interpolación , como por ejemplo con style=”{{some expression}}”.

Si esta técnica parece buena , tiene sus inconvenientes. En el ejemplo anterior se ve fácil , pero en aplicaciones web completas tener que leer tanto la maqueta como el Javascript para crear el CSS de forma correcta puede ser inmanejable.

Es por esto que Angular proporciona las directivas ng-class y ng-style.Las dos reciben una expresión. El resultado de evaluar esta expresión puede ser uno de los siguientes:

  • Una cadena representando una lista de clases de CSS separadas por espacios
  • Un array de class names
  • Un mapa de class names a boolean values

Imaginemos que quieres mostrar errores y warnings a tus usuarios en una localización estandar en la cabecera. Utilizando la directiva ng-class, puedes hacer lo siguiente:

.error {
background-color: red;
}
.warning {
background-color: yellow;
}
<div ng-controller='HeaderController'>
...
<div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>
…
<button ng-click='showError()'>Simulate Error</button>
<button ng-click='showWarning()'>Simulate Warning</button>
</div>
function HeaderController($scope) {
$scope.isError = false;
$scope.isWarning = false;
$scope.showError = function() {
$scope.messageText = 'This is an error!';
$scope.isError = true;
$scope.isWarning = false;
};
$scope.showWarning = function() {
$scope.messageText = 'Just a warning. Please carry on.';
$scope.isWarning = true;
$scope.isError = false;
};
}

You can even do nifty things like highlighting a selected row in a table. Let’s say we’re
building a restaurant directory and we want to highlight a row that the user clicks on.
In our CSS, we set up the style for a highlighted row:

.selected {
background-color: lightgreen;
}

In the template, we set ng-class to {selected: $index==selectedRow}. This has the
effect of setting the selected class when our model property called selectedRow matches
the ng-repeat’s $index. We’ll also set up an ng-click to notify our controller as to
which row the user clicks:

<table ng-controller='RestaurantTableController'>
<tr ng-repeat='restaurant in directory' ng-click='selectRestaurant($index)'
ng-class='{selected: $index==selectedRow}'>
<td>{{restaurant.name}}</td>
<td>{{restaurant.cuisine}}</td>
</tr>
</table>

In our JavaScript, we just set up some dummy restaurants and create the selectRow
function:

function RestaurantTableController($scope) {
$scope.directory = [{name:'The Handsome Heifer', cuisine:'BBQ'},
{name:'Green's Green Greens', cuisine:'Salads'},
{name:'House of Fine Fish', cuisine:'Seafood'}];
$scope.selectRestaurant = function(row) {
$scope.selectedRow = row;
};
}

Considerations for src and href Attributes

When data binding to an <img> or <a> tag, the obvious path of using {{ }} in the src or
href attributes won’t work well. Because browsers are aggressive about loading images
parallel to other content, Angular doesn’t get a chance to intercept data binding requests.
While the obvious syntax for an <img> might be:

<img src="/images/cats/{{favoriteCat}}">

Instead, you should use the ng-src attribute and write your template as:

<img ng-src="/images/cats/{{favoriteCat}}">

Similarly, for the <a> tag, you should use ng-href:

<a ng-href="/shop/category={{numberOfBalloons}}">some text</a>

Expressions

The goal behind the expressions that you use in templates is to let you be as clever as
you need to be to create hooks between your template, your application logic, and your
data, but at the same time prevent application logic from sneaking into the template.
Until this point, we’ve been mostly using references to data primitives as the expressions
passed to Angular directives. But these expressions can do much more. You can do simple math (+, -, /, *, %), make comparisons (==, !=, >, <, >=, ⇐), perform boolean logic (&&, ||, !) and bitwise operations (^, &, |). You can call functions you expose on $scope in your controller and you can reference arrays and object notation ([ ], { }, .).

All of these are valid examples of expressions:

<div ng-controller='SomeController'>
<div>{{recompute() / 10}}</div>
<ul ng-repeat='thing in things'>
<li ng-class='{highlight: $index % 4 >= threshold($index)}'>
{{otherFunction($index)}}
</li>
</ul>
</div>

The first expression here, recompute() / 10, while valid, is a good example of putting
logic in the template, and should be avoided. Keeping a separation of responsibilities
between your view and controllers ensures that they’re easy to reason and easy to test.
While you can do quite a lot with expressions, they are computed with a custom parser
that’s part of Angular. They are not evaluated using JavaScript’s eval(), and are considerably more restrictive.

Instead, they are evaluated using a custom parser that comes with Angular. In it, you
won’t find looping constructs (for, while, and so on), flow-of-control operators (if-else,
throw) or operators that modify data (++, –). When you need these types of operations,
do them in your controller or via a directive.

Though expressions are more restrictive than JavaScript in many ways, they are more
forgiving to undefined and null. Instead of throwing a NullPointerException error,
templates will simply render nothing. This allows you to safely use model values that haven’t been set yet, and have them appear in the UI as soon as they get populated.

Separating UI Responsibilities with Controllers

Controllers have three responsibilities in your app:
• Set up the initial state in your application’s model
• Expose model and functions to the view (UI template) through $scope
• Watch other parts of the model for changes and take action

We’ve seen many examples of the first two in this chapter already. We’ll get to that last
one in a bit. The conceptual purpose of controllers, however, is to provide the code or
logic to execute the user’s wishes as they interact with the view.

To keep your controllers small and manageable, our recommendation is that you create one controller per functional area in your view. That is, if you have a menu, create a MenuController. If you have a navigational breadcrumb, write a BreadcrumbControl ler, and so on.You’re probably starting to get the picture, but to be explicit, controllers are tied to a specific piece of the DOM that they’re in charge of managing.

The two main ways of associating a controller with a DOM node are specifying it in the template by declaring it in an ng-controller attribute, and associating it with a dynamically loadable DOM template fragment, called a view, through a route.We’ll talk about views and routes later in this chapter.

If you have complex sections of your UI, you can keep your code simple and maintainable,by creating nested controllers that can share model and functions through an inheritance tree. Nesting controllers is simple; you do it by simply assigning a controller to a DOM element that is inside another one, like so:

<div ng-controller="ParentController">
<div ng-controller="ChildController">...</div>
</div>

Though we express this as nested controllers, the actual nesting happens in scopes. The $scope passed to a nested controller prototypically inherits from its parent controller’s $scope. In this case, this means that the $scope passed to ChildController will have access to all the properties of the $scope passed to ParentController.

Publishing Model Data with Scopes

The $scope object passed to our controllers is the mechanism we use to expose model
data to views. You may have other data in your application, but Angular only considers
it part of the model when it can reach these properties through a scope. You can think
of scopes as a context that you use to make changes to your model observable.

We’ve seen many examples of setting up scopes explicitly, as in $scope.count = 5.
There are also some indirect ways to set up the model from the template itself. You can
do so in the following ways:

  • Through an expression. Since expressions execute in the context of the controller’s scope associated with their element, setting properties in expressions is the same as setting a property of the controller’s scope. That is, doing this:
<button ng-click='count=3'>Set count to three</button>

has the same effect as doing this:

<div ng-controller='CountController'>
<button ng-click='setCount()'>Set count to three</button>
</div>

with your CountController defined as:

function CountController($scope) {
$scope.setCount = function() {
$scope.count=3;
}
}
  • Using ng-model on a form input. As with expressions, the model specified as the argument for ng-model also works within the scope of the enclosing controller. The one addition is that this creates a bi-directional data binding between the form field state and your specified model.

Observing Model Changes with $watch

Possibly the most used of all scope functions is $watch, which notifies you when parts
of your model change. You can watch individual object properties and computed results
(functions), really anything that could be accessed as a property or computed as a Java‐
Script function. The function’s signature is:

$watch(watchFn, watchAction, deepWatch)

The details of each parameter are as follows:

  • watchFn: This parameter is a string with an Angular expression or a function that returns the current value of the model that you want to watch. This expression will be evaluated multiple times, so you need to make sure that it has no side effects. That is, it can be called multiple times without changing state. For the same reason, watch expressions should be computationally cheap. If you’ve passed in an Angular expression in a string, it will be evaluated against objects available to the scope it’s called on.
  • watchAction: This is the function or expression to be called when the watchFn changes. In the function form, it receives the new and old values of watchFn as well as a reference to the scope. Its signature is function(newValue, oldValue, scope).
  • deepWatch: If set to true, this optional boolean parameter tells Angular to examine each property within the watched object for changes. You’d use this if you wanted to watch individual elements in an array or properties in an object instead of just a simple value. As Angular needs to walk the array or object, this can be computationally expensive if the collection is large.

The $watch function returns a function that will de-register the listener when you no
longer want to receive change notifications.If we wanted to watch a property and then later de-register it, we would use the following:

...
var dereg = $scope.$watch('someModel.someProperty', callbackOnChange());
…
dereg();

Let’s revisit our shopping cart scenario from Chapter 1 for a full example. Let’s say that
we want to apply a $10 discount when the customer adds more than $100 worth of
merchandise to her cart. For a template, we’ll use:

<div ng-controller="CartController">
<div ng-repeat="item in items">
<span>{{item.title}}</span>
<input ng-model="item.quantity">
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
</div>
<div>Total: {{totalCart() | currency}}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>Subtotal: {{subtotal() | currency}}</div>
</div>

With a CartController, it would look like the following:

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.totalCart = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
return total;
}
$scope.subtotal = function() {
return $scope.totalCart() - $scope.discount;
};
function calculateDiscount(newValue, oldValue, scope) {
$scope.bill.discount = newValue > 100 ? 10 : 0;
}
$scope.$watch($scope.totalCart, calculateDiscount);
}

Notice that at the bottom of CartController, we’ve set up a watch on the value of
totalCart() which we use to sum up the total price for this purchase. Whenever this
value changes, the watch will call calculateDiscount(), and we get to set the discount
to an appropriate value. If the total is $100, we’ll set the discount to $10. Otherwise, the
discount will be $0.

Performance Considerations in watch()

The preceding example executes correctly, but there is a potential problem with performance.Though it isn’t obvious, if you put a debugger breakpoint in totalCart(),
you’d see that it gets called six times to render this page. Though you’d never notice it
in this application, in more complex apps, running it six times could be an issue.

Why six? Three of them we can trace pretty easily, as it runs one time each in:
• The template as {{totalCart() | currency}}
• The subtotal() function
• The $watch() function
Then Angular runs all of these again, bringing us to six. Angular does this to verify that
transitive changes in your model have fully propagated and your model has settled.

Angular does this checking by making a copy of all watched properties and comparing
them to the current value to see if they’ve changed. In fact, Angular may run this up to
ten times to ensure full propagation. If changes are still occurring after ten iterations,
Angular exits with an error. If that occurs, you probably have a dependency loop that
you’ll need to fix.

Though you currently need to worry about this, by the time you’ve finished this book
it may be a non-issue. While Angular has had to implement data binding in JavaScript,
we’ve been working with the TC39 folks on a low-level native implementation called
Object.observe(). With this in place, Angular will automatically use Object.ob
serve() wherever present to give you native-speed data binding.

As you’ll see in the next chapter, Angular has a nice Chrome debugging extension called
Batarang that will automatically highlight expensive data bindings for you.Now that we know about this issue, there are a few ways we can solve it. One way would be to create a $watch on changes to the items array and just recalculate the total, discount,and subtotal as properties on the $scope.To do this, we’d update the template to use these properties:

<div>Total: {{bill.total | currency}}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>Subtotal: {{bill.subtotal | currency}}</div>

Then, in JavaScript, we’d watch the items array, and call a function to calculate the totals on any change to that array, like so:

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
var calculateTotals = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalCart = total;
$scope.bill.discount = total > 100 ? 10 : 0;
$scope.bill.subtotal = total - $scope.bill.discount;
};
$scope.$watch('items', calculateTotals, true);
}

Notice here that the $watch specified items as a string. This is possible because the
$watch function can take either a function (as we did previously) or a string. If a string
is passed to the $watch function, then it will be evaluated as an expression in the scope
of the $scope it’s called on.

This strategy might work well for your app. However, since we’re watching the items
array, Angular will have to make a copy of it to compare it for us. For a large list of items,
it may perform better if we just recalculate the bill properties every time Angular evaluates the page. We can do this by creating a $watch with only a watchFn that will recalculate our properties like this:

$scope.$watch(function() {
var total = 0;
for (var i = 0; i < $scope.items.length; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalCart = total;
$scope.bill.discount = total > 100 ? 10 : 0;
$scope.bill.subtotal = total - $scope.bill.discount;
});

Watching multiple things

What if you want to watch multiple properties or objects and execute a function whenever any of them change? You’d have two basic options:
• Put them into an array or object and pass in deepWatch as true.
• Watch a concatenated value of the properties.

In the first case, if you’ve got an object with two properties a and b in your scope, and
want to execute the callMe() function on change, you could watch both of them, like
so:

$scope.$watch('things.a + things.b', callMe(...));

Of course, a and b could be on different objects, and you could make the list as long as
you like. If the list is long, you would likely write a function that returns the concatenated
value rather than relying on an expression for the logic.

In the second case, you might want to watch all the properties on the things object. In
this case, you could do this:

$scope.$watch('things', callMe(...), true);

Here, passing in true as the third parameter asks Angular to walk the properties of
things and call callMe() on a change to any of them. This works equally well on an
array as it does here on an object.

Organizing Dependencies with Modules

En aplicaciones ya algo complejas , organizar toda la funcionalidad de tu código en áreas de responsabilidad es a menudo una ardua tarea. Hemos visto como los controladores nos proporcionan un espacio para poner código que expone las funciones y los datos que corresponden al template de la vista. Pero que hay sobre el resto del código en el que necesitamos apoyarnos en nuestras aplicaciones? El lugar más obvio para poner esto sería en funciones dentro del controlador.

Esto funciona bien en aplicaciones pequeñas y en los ejemplos sobre los que estamos trabajando , pero rápidamente se convierte en inmanejable en aplicaciones reales.Los controladores terminarían siendo difíciles de mantener.

Introducir módulos.  Con los módulos tenemos una forma de agrupar dependencias para una área funcional dentro de nuestra aplicación , y un mecanismo para automáticamente resolver dependencias (también conocido como inyección de dependencias). Genéricamente  llamamos a estas dependencias servicios , ya que proporcionan servicios específicos a nuestra aplicación.

Por ejemplo , si en nuestra web de tienda online un controller necesita sacar una lista de items de venta desde el servidor , querríamos tener algún objeto – llamemosle Items – que se encarga de recoger los datos desde el servidor. El objeto Items , por su parte , necesita alguna forma de comunicar con la base de datos en el servidor a través de XHR o WebSockets. Haciendo esto con módulos tendría el siguiente aspecto:

function ItemsViewController($scope) {
// make request to server
…
// parse response into Item objects
…
// set Items array on $scope so the view can display it
...
}

Aunque esto funciona , tiene algunos problemas potenciales:

  • So algún otro controller también necesita sacar los Items desde el servidor, tendriamos que replicar el código –> MALO para mantener el código
  • Con otros factores como autenticación, parsing complexity, etc se hace dificil delimitar las fronteras de responsabilidad de este objeto controller y la lectura del código se hace dificil.
  • To unit test this bit of code, we’d either need to actually have a server running, or monkey patch XMLHttpRequest to return mock data. Having to run the server will make tests very slow, it’s a pain to set up, and it usually introduces flakiness into tests. The monkey patching route solves the speed and flakiness problems, but it means you have to remember to un-patch any patched objects between tests, and it brings additional complexity and brittleness by forcing you to specify the exact on-the-wire format for your data (and in having to update the tests whenever this format changes).

Con módulos , y la inyección de dependencia que conseguimos de ellos , podemos codificar nuestro controller de manera más simple:

function ShoppingController($scope, Items) {
$scope.items = Items.query();
}

Probablemente,  te estes preguntando a ti mismo de donde viene Items. Pues en ese código se asume que hemos definido Items como un service.

Services son objetos singleton (single-instance) que se encargan de las tareas necesarias que apoyan la funcionalidad de tu aplicación. Angular viene con muchos servicios como $location , para interactuar con el objeto location del navegador , $route , para intercambiar entre vistas basadas en los cambios del location (URL) y $http para comunicar con servidores.

Puedes , y deberias , crear tus propios servicios para encapsular todas las treas únicas a tu aplicación. Los servicios pueden ser compartidos para todos los controllers que los necesiten. De hecho , son un buen mecanismo a utilizar cuando necesitas comunicación entre controllers y compartir estado.

Los servicios que lleva angular por defecto comienzan con $, así que es buena idea que no empiecen por $ los servicios que te crees para evitar colisiones.

Se definen módulos con el module object’s API. Hay tres funciones para crear servicios genéricos, con diferentes niveles de complejidad y habilidad:

  • provider(name, Object OR constructor() ) : 
    A configurable service with complex creation logic. If you pass an Object, it should have a function named $get that returns an instance of the service. Otherwise, Angular assumes you’ve passed a constructor that, when called, creates the instance.
  • factory(name, $getFunction() )
    A non-configurable service with complex creation logic. You specify a function that, when called, returns the service instance. You could think of this as provider(name, { $get: $getFunction() } ).
  • service(name, constructor() )
    A non-configurable service with simple creation logic. Like the constructor option with provider,Angular calls it to create the service instance.

We’ll look at the configuration option for provider() later, but let’s discuss an example
with factory() for our preceding Items example. We can write the service like this:

// Create a module to support our shopping views
var shoppingModule = angular.module('ShoppingModule', []);
// Set up the service factory to create our Items interface to the
// server-side database
shoppingModule.factory('Items', function() {
var items = {};
items.query = function() {
// In real apps, we'd pull this data from the server...
return [
{title: 'Paint pots', description: 'Pots full of paint', price: 3.95},
{title: 'Polka dots', description: 'Dots with polka, price: 2.95},
{title: 'Pebbles', description: 'Just little rocks', price: 6.95}
];
};
return items;
});

When Angular creates the ShoppingController, it will pass in $scope and the new
Items service that we’ve just defined. This is done by parameter name matching. That
is, Angular looks at the function signature for our ShoppingController class, and
notices that it is asking for an Items object. Since we’ve defined Items as a service, it
knows where to get it.

The result of looking up these dependencies as strings means that the arguments of
injectable functions like controller constructors are order-independent. So instead of
this:

function ShoppingController($scope, Items) {...}

we can write this:

function ShoppingController(Items, $scope) {...}

and it all still functions as we intended.

To get this to work with our template, we need to tell the ng-app directive the name of
our module, like the following:

<html ng-app='ShoppingModule'>

To complete the example, we could implement the rest of the template as:

<body ng-controller="ShoppingController">
 <h1>Shop!</h1>
 <table>
 <tr ng-repeat='item in items'>
 <td>{{item.title}}</td>
 <td>{{item.description}}</td>
 <td>{{item.price | currency}}</td>
 </tr>
 </table>

How Many Modules Do I Need?

As services themselves can have dependencies, the Module API lets you define dependencies for your dependencies.In most applications, it will work well enough to create a single module for all the code you create and put all of your dependencies in it.

If you use services or directives from third-party libraries, they’ll come with their own modules. As your app depends on them, you’d refer to them as dependencies of your application’s module.For instance, if you include the (fictitious) modules SnazzyUIWidgets and SuperData‐Sync, your application’s module declaration would look like this:

var appMod = angular.module('app', ['SnazzyUIWidgets', 'SuperDataSync'];

Formatting Data with Filters

Filters allow you to declare how to transform data for display to the user within an
interpolation in your template. The syntax for using filters is:

{{ expression | filterName : parameter1 : ...parameterN }}

where expression is any Angular expression, filterName is the name of the filter you
want to use, and the parameters to the filter are separated by colons. The parameters
themselves can be any valid Angular expression.

Angular comes with several filters, like currency, which we’ve seen:

{{12.9 | currency}}

This bit of code will display the following:

$12.90

We put this declaration in the view (rather than in the controller or model) because the
dollar sign in front of the number is only important to humans, and not to the logic we
use to process the number.

Other filters that come with Angular include date, number, uppercase, and more.
Filters can also be chained with additional pipe symbols in the binding. For example,
we can format the previous example for no digits after the decimal by adding the number
filter, which takes the number of decimals to round to as a parameter. So:

{{12.9 | currency | number:0 }}

displays:

$13

You’re not limited to the bundled filters, and it is simple to write your own. If we wanted to create a filter that title-cased strings for our headings, for example, we could do so as follows:

var homeModule = angular.module('HomeModule', []);
homeModule.filter('titleCase', function() {
var titleCaseFilter = function(input) {
var words = input.split(' ');
for (var i = 0; i < words.length; i++) {
words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
}
return words.join(' ');
};
return titleCaseFilter;
});

With a template like this:

<body ng-app='HomeModule' ng-controller="HomeController">
<h1>{{pageHeading | titleCase}}</h1>
</body>

and inserting the pageHeading as a model variable via a controller:

function HomeController($scope) {
$scope.pageHeading = 'behold the majesty of your page title';
}

Changing Views with Routes and $location

Though AJAX apps are technically single-page apps (in the sense that they only load an
HTML page on the first request, and then just update areas within the DOM thereafter),
we usually have multiple sub-page views that we show or hide from the user, as appropriate.

We can use Angular’s $route service to manage this scenario for us. Routes let you
specify that, for a given URL that the browser points to, Angular should load and display a template, and instantiate a controller to provide context for the template.

You create routes in your application by calling functions on the $routeProvider service as a configuration block. It goes something like this pseudo-code:

var someModule = angular.module('someModule', [...module dependencies...])
someModule.config(function($routeProvider) {
$routeProvider.
when('url', {controller:aController, templateUrl:'/path/to/tempate'}).
when(...other mappings for your app...).
…
otherwise(...what to do if nothing else matches...);
)};

The preceding code says that when the browser’s URL changes to the specified URL, Angular will load the template in /path/to/template, and associate the root element of this template with aController (as if we’d typed ng-controller=aController).

The otherwise() call in the last line tells the route where to go if nothing else matches.
Let’s put it to use. We’re building an email app that will easily win out over Gmail,
Hotmail, and all the others. We’ll call it…A-Mail. For now, let’s start simply. We’ll have
a first view that displays a list of email messages with a date, title, and the sender. When
you click a message, it should show you a new view with the body of that message.
Due to browser security restrictions, if you’re trying the code out yourself,
you’ll need to serve it from a web server instead of just file://. If you
have python installed, you could serve it by executing python -m Sim
pleHTTPServer 8888 from your working directory.

For the main template, we’ll do something a bit different. Instead of putting everything
in the first page loaded, we’ll just create a layout template that we’ll put our views into.
We’ll place everything that persists from view to view, like our menus, here. In this case,
we’ll just display a heading with the name of our app. We’ll then use the ng-view directive to tell Angular where we want our views to appear.

index.html

<html ng-app="AMail">
<head>
<script src="src/angular.js"></script>
<script src="src/controllers.js"></script>
</head>
<body>
<h1>A-Mail</h1>
<div ng-view></div>
</body>
</html>

As our view templates will be inserted into the shell we just created, we can write them
as partial HTML documents. For the email list, we’ll use ng-repeat to iterate through
a list of messages and render them into a table.

list.html

<table>
<tr>
<td><strong>Sender</strong></td>
<td><strong>Subject</strong></td>
<td><strong>Date</strong></td>
</tr>
<tr ng-repeat='message in messages'>
<td>{{message.sender}}</td>
<td><a href='#/view/{{message.id}}'>{{message.subject}}</td>
<td>{{message.date}}</td>
</tr>
</table>

Notice here that we’re going to let the user navigate to a particular message by clicking
on the subject. We’ve data bound the URL to message.id, so clicking on a message with
id=1 will take the user to /#/view/1. We’ll use this navigation-by-url, also known as deeplinking,in the message detail view’s controller, to make a particular message available to the detail view.

To create this message detail view, we’ll create a template that displays properties from
a single message object.
detail.html

<div>
	<strong>Subject:</strong> {{message.subject}}
</div>
<div>
	<strong>Sender:</strong> {{message.sender}}
</div>
<div>
	<strong>Date:</strong> {{message.date}}
</div>
<div>
	<strong>To:</strong> <span ng-repeat='recipient in message.recipients'>{{recipient}}
	</span>
	<div>{{message.message}}</div>
	<a href='#/'>Back to message list</a>
</div>

Now, to associate these templates with some controllers, we’ll configure the $routePro
vider with the URLs that invoke our controllers and templates.

controllers.js

//A-MAIL
// Create a module for our core AMail services
var aMailServices = angular.module('AMail', []);

// Set up our mappings between URLs, templates, and controllers
function emailRouteConfig($routeProvider) {
	// Notice that for the detail view, we specify a parameterized URL component
	// by placing a colon in front of the id
	$routeProvider.when('/', {
							controller: ListController,
							templateUrl: 'list.html'
							}).
					when('/view/:id', {
							controller: DetailController,
							templateUrl: 'detail.html'
							}).
					otherwise({
						redirectTo: '/'
					});
}

// Set up our route so the AMail service can find it
aMailServices.config(emailRouteConfig);

// Some fake emails
messages = [
            {
			id: 0, sender: 'jean@somecompany.com', subject: 'Hi there, old friend',
			date: 'Dec 7, 2013 12:32:00', recipients: ['greg@somecompany.com'],
			message: 'Hey, we should get together for lunch sometime and catch up.'
						+'There are many things we should collaborate on this year.'
			}, 
			{
			id: 1, sender: 'maria@somecompany.com',
			subject: 'Where did you leave my laptop?',
			date: 'Dec 7, 2013 8:15:12', recipients: ['greg@somecompany.com'],
			message: 'I thought you were going to put it in my desk drawer.'
			+'But it does not seem to be there.'
			}, {
			id: 2, sender: 'bill@somecompany.com', subject: 'Lost python',
			date: 'Dec 6, 2013 20:35:02', recipients: ['greg@somecompany.com'],
			message: "Nobody panic, but my pet python is missing from her cage.'
			+'She doesn't move too fast, so just call me if you see her."
			} 
	];

// Publish our messages for the list template
function ListController($scope) {
	$scope.messages = messages;
}

// Get the message id from the route (parsed from the URL) and use it to
// find the right message object.
function DetailController($scope, $routeParams) {
	$scope.message = messages[$routeParams.id];
}

We’ve created the basic structure for an app with many views. We switch views by
changing the URL. This means that the forward and back buttons just work for users.
Users are able to bookmark and email links to views within the app, even though there
is only one real HTML page.

Talking to Servers

Okay, enough messing around. Real apps generally talk to real servers. Mobile apps and the emerging Chrome desktop apps may be exceptions, but for everything else, whether you want persistence in the cloud or real-time interactions with other users, you probably want your app to talk to a server.

For this, Angular provides a service called $http. It has an extensive list of abstractions
that make it easier to talk to servers. It supports vanilla HTTP, JSONP, and CORS. It includes security provisions to protect from both JSON vulnerabilities and XSRF. It lets you easily transform the request and response data, and it even implements simple caching.

Let’s say we want to retrieve products for our shopping site from a server instead of from
our silly in-memory mocks. Writing the server bits is beyond the scope of this book, so
let’s just imagine that we’ve created a service that will return a list of products as JSON
when you make a query to /products.Given a response that looks like this:

[
{
"id": 0,
"title": "Paint pots",
"description": "Pots full of paint",
"price": 3.95
},
{
"id": 1,
"title": "Polka dots",
"description": "Dots with that polka groove",
"price": 12.95
},
{
"id": 2,
"title": "Pebbles",
"description": "Just little rocks, really",
"price": 6.95
}
...etc...
]

we could write the query like so:

function ShoppingController($scope, $http) {
$http.get('/products').success(function(data, status, headers, config) {
$scope.items = data;
});
}

and use it in a template like this:

<body ng-controller="ShoppingController">
<h1>Shop!</h1>
<table>
<tr ng-repeat="item in items">
<td>{{item.title}}</td>
<td>{{item.description}}</td>
<td>{{item.price | currency}}</td>
</tr>
</table>
</body>

As we learned previously, we would be better off in the long run by delegating the work
of talking to the server to a service that could be shared across controllers. We’ll take a
look at this structure and the full range of $http functions in Chapter 5.

Changing the DOM with Directives

Directives extend HTML syntax, and are the way to associate behavior and DOM transformations with custom elements and attributes. Through them, you can create reusable UI components, configure your application, and do almost anything else you can imagine wanting to do in your UI template.

You can write apps with the built-in directives that come with Angular, but you’ll likely
run into situations where you want to write your own. You’ll know it’s time to break
into directives when you want to deal with browser events or modify the DOM in a way
that isn’t already supported by the built-in directives. This code of yours belongs in a
directive that you write, and not in a controller, service, or any other place in your app.
As with services, you define directives through the module object’s API by calling its
directive() function, where directiveFunction is a factory function that defines
your directive’s features.

var appModule = angular.module('appModule', [...]);
appModule.directive('directiveName', directiveFunction);

Writing the directive factory function is a deep area, and we’ve dedicated an entire
chapter to it in this book. To whet your appetite, though, let’s look at a simple example.

HTML5 has a great new attribute called autofocus that will place keyboard focus on an
input element. You’d use it to let the user start interacting with the element via his
keyboard without having to click on it first. This is great, as it lets you declaratively
specify what you want the browser to do without having to write any JavaScript. But
what if you wanted to place focus on some non-input element, like a link or any div?
And what if you wanted it to work on non-HTML5 browsers as well? We could do it
with a directive.

var appModule = angular.module('app', []);
appModule.directive('ngbkFocus', function() {
return {
link: function(scope, element, attrs, controller) {
element[0].focus();
}
};
});

Here, we’re returning the directive configuration object with its link function specified.
The link function gets a reference to the enclosing scope, the DOM element it lives on,
an array of any attributes passed to the directive, and the controller on the DOM element, if it exists. Here, we only need to get at the element and call its focus() method.
We can then use it in an example like so:

index.html

<html lang='en' ng-app='app'>
...include angular and other scripts...
<body ng-controller="SomeController">
<button ng-click="clickUnfocused()">
Not focused
</button>
<button ngbk-focus ng-click="clickFocused()">
I'm very focused!
</button>
<div>{{message.text}}</div>
</body>
</html>

controllers.js

function SomeController($scope) {
$scope.message = { text: 'nothing clicked yet' };
$scope.clickUnfocused = function() {
$scope.message.text = 'unfocused button clicked';
};
$scope.clickFocused = function {
$scope.message.text = 'focus button clicked';
}
}
var appModule = angular.module('app', ['directives']);

When the page loads, the user will see the button labeled “I’m very focused!” with the
focus highlight. Hitting the spacebar or the enter key will cause a click and invoke the
ng-click, which will set the div text to ‘focus button clicked’. Opening this example in
a browser, we’d see something that looks like:

Sin título

Validating User Input

Angular automatically augments <form> elements with several nice features suitable for
single-page applications (ng-form directive).One of these nice features is that Angular lets you declare valid states for inputs within the form and allow submission only when the entire set of elements is valid.

For example, if we’re creating a signup form where we require entering a name and
email, but have an optional age field, we can validate several user entries before they are submitted to the server. Loading the example that follows into a browser will display
what is shown in Figure 2-5.

Sin título
Figure 2-5. Form validation

We’d want to make sure the user had entered text in the name fields, that he had entered a properly formed email address, and that if he entered an age, it was valid.
We can do this all in the template, using Angular’s extensions to <form> and the various
input elements, like this:

<h1>Sign Up</h1>
<ng-form name='addUserForm'>
<div>First name: <input ng-model='user.first' required></div>
<div>Last name: <input ng-model='user.last' required></div>
<div>Email: <input type='email' ng-model='user.email' required></div>
<div>Age: <input type='number'
ng-model='user.age'
ng-maxlength='3'
ng-minlength='1'></div>
<div><button>Submit</button></div>
</ng-form>

Notice that we’re using the required attribute and input types for email and number
from HTML5 to do our validation on some of the fields. This works great with Angular,
and in older non-HTML5 browsers, Angular will polyfill these with directives that perform the same jobs.

We can then add a controller to this to handle the submission by changing the form to
reference it.

<ng-form name='addUserForm' ng-controller="AddUserController">

Inside the controller, we can access the validation state of the form through a property
called $valid. Angular will set this to true when all the inputs in the form are valid. We
can use this $valid property to do nifty things such as disabling the Submit button
when the form isn’t completed yet.

We can prevent form submission in an invalid state by adding ng-disabled to the
Submit button:

<button ng-disabled='!addUserForm.$valid'>Submit</button>

Finally, we might want the controller to tell the user she’s been successfully added. Our
final template would look like:

<h1>Sign Up</h1>
<form name='addUserForm' ng-controller="AddUserController">
<div ng-show='message'>{{message}}</div>
<div>First name: <input name='firstName' ng-model='user.first' required></div>
<div>Last name: <input ng-model='user.last' required></div>
<div>Email: <input type='email' ng-model='user.email' required></div>
<div>Age: <input type='number'
ng-model='user.age'
ng-maxlength='3'
ng-min='1'></div>
<div><button ng-click='addUser()'
ng-disabled='!addUserForm.$valid'>Submit</button>
</ng-form>

with controller:

function AddUserController($scope) {
$scope.message = '';
$scope.addUser = function () {
// TODO for the reader: actually save user to database...
$scope.message = 'Thanks, ' + $scope.user.first + ', we added you!';
};
}

Moving On

In the last two chapters, we looked at all the most commonly used features in the Angular framework. For each feature discussed, there are many additional details we have yet to cover. In the next chapter, we’ll get you going by examining a typical development workflow.

dsfsd

fsd

fsd

fsd

fsd

fs

d

AngularJS Tutorial

[Fuente: http://docs.angularjs.org/tutorial]

En este tutorial introducimos AngularJS haciendo una aplicación web de ejemplo. La app que haremos será un catálogo que muestra una lista de dispositivos Android, permite filtrar la lista y ver los detalles de un dispositivo.

Según avances por este tutorial:

  • Ver ejemplos de cómo utilizar client-side data binding y dependency injection para construir vistas dinámicas de datos que cambian inmediatamente en respuesta a acciones del usuario.
  • Ver cómo Angular crea listeners sobre tus datos sin la necesidad de programar manipulación DOM
  • Aprende de una forma fácil a testear tus aplicaciones web
  • Aprende cómo utilizar servicios Angular para hacer tareas web comunes, como recuperar datos para mostrarlo, de una forma fácil.
  • Y todo esto funciona en todos los navegadores!

Cuando finalices este tutorial serás capaz de:

  • Crear una aplicación dinámica que funcione en cualquier browser.
  • Definir las diferencias entre Angular y otros frameworks Javascript
  • Entender cómo funciona el data binding en AngularJS
  • Utilizar el angular-seed project como base para empezar proyectos nuevos
  • Crear y ejecutar test
  • Identificar recursos para aprender más sobre AngularJS

You can go through the whole tutorial in a couple of hours or you may want to spend a pleasant day really digging into it. If you’re looking for a shorter introduction to AngularJS, check out the Getting Started document.

Working with the code

You can follow this tutorial and hack on the code in either the Mac/Linux or the Windows environment. The tutorial relies on the use of Git versioning system for source code management. You don’t need to know anything about Git to follow the tutorial. Select one of the tabs below and follow the instructions for setting up your computer.

  1. You will need Node.js and Karma to run unit tests, so please verify that you have Node.js v0.8 or better installed and that the node executable is on your PATH by running the following command in a terminal window:
    1. node –version

    Additionally install Karma if you don’t have it already:

    1. npm install -g karma
  2. You’ll also need Git, which you can get from the Git site.
  3. Clone the angular-phonecat repository located at Github by running the following command:
    1. git clone git://github.com/angular/angular-phonecat.git

    This command creates the angular-phonecat directory in your current directory.

  4. Change your current directory to angular-phonecat:
    1. cd angular-phonecat

    The tutorial instructions assume you are running all commands from the angular-phonecat directory.

    You should run all git commands from Git bash.

    Other commands like test.bat or e2e-test.bat should be executed from the Windows command line.

  5. You need an http server running on your system, but if you don’t already have one already installed, you can use node to run scriptsweb-server.js, a simple bundled http server.

The last thing to do is to make sure your computer has a web browser and a good text editor installed. Now, let’s get some cool stuff done!

Get Started!