> Manuales > Manual de AngularJS

Los componentes en AngularJS mantienen la lógica en controladores independientes, que debemos definir durante la declaración component.

El desarrollo en Angular ahora está basado en componentes, una tendencia que también encontraremos en la versión 2.0 del framework, por lo que conviene ir familiarizándose con ella. Por otra parte nos ofrece diversas ventajas y hasta simplicidad con respecto al desarrollo con directivas, por lo que nos interesará invertir algo de tiempo en ponernos al día.

Si quieres saber cómo trabajar con componentes en Angular y empiezas desde cero, te recomendamos comenzar por la lectura de un artículo anterior donde se trataron las bases del desarrollo basado en componentes. En este artículo vamos a explicar cómo incorporar lógica (programación) en un componente, permitiendo la posibilidad de realizar cálculos o responder a acciones e interacción por parte del usuario.

Controller en la declaración component

Como ya estamos acostumbrados en general cuando usamos Angular, los controladores son el lugar donde comenzamos a aplicar lógica de la aplicación, aunque también sabemos que muchas veces éstos apoyan parte de su comportamiento en otro tipo de artefactos como factorías y servicios.

En el caso de componentes todo sigue igual. Tendremos un controlador que nos permitirá escribir el código a ejecutar para la inicialización de cada instancia del componente y para definir comportamientos ante diversas situaciones.

El controlador se debe definir al declarar el componente. Ya sabes que para crear el componente usas la función de angular "component". A esa función le pasamos un objeto con diversos datos, como el template HTML del componente. Todo eso se vió en el anterior artículo.

Para definir el controlador, al objeto de declaración component, le pasamos una nueva propiedad llamada "controller". En esa propiedad colocamos una función que será nuestro propio controlador.

Podemos escribir directamente el código de nuestro controlador con una función anónima, tal como ves en el siguiente código:

angular.module('cuentaClics', [])
.component('cuentaClics', {
  templateUrl: './components/cuenta-clics/cuenta-clics.html',
  controller: function(){
    var vm  = this;
    vm.numClics = 0;
    vm.incrementaClic = function(){
      vm.numClics ++;
    }
  }
});

También como alternativa es posible indicar el nombre de un controlador que haya definido en éste u otro módulo. Por tanto el código que ves a continuación tendrá el exactamente el mismo efecto:

angular.module('cuentaClics', [])
.controller('CuentaClicsController', function(){
  var vm  = this;
  vm.numClics = 0;
  vm.incrementaClic = function(){
    vm.numClics ++;
  }
})
.component('cuentaClics', {
  templateUrl: './components/cuenta-clics/cuenta-clics.html',
  controller: 'CuentaClicsController'
});

Como has comprobado en este sencillo controlador tenemos las dos cosas que se suelen encontrar en ellos, datos como es el caso de "numClics" y funciones para realizar comportamientos, como es el caso de "incrementaClic".

Acceso a los controladores dentro del HTML de un componente

Ahora tenemos que ver cómo podemos acceder a las propiedades de un controlador dentro del template de un componente, ya sea para visualizar uno de sus datos o invocar alguno de sus métodos.

Ésto se realiza tal como venimos operando con controladores en el pasado, por medio de una variable que hace referencia al controlador y mediante la cual se accede a sus propiedades y métodos. La única cosa que debemos saber es que en components de AngularJS los controladores tienen el nombre de $ctrl dentro de las vistas.

Nota: Nota: Con el método de trabajo que se conoce con "Controller As" éramos capaces de definir diversos nombres para conocer a los controladores dentro de diversos scopes que puede tener una aplicación, de modo que se puedan anidar controladores y no tener problemas para acceder a datos o métodos de controladores específicos, incluso cuando existen propiedades y valores que tienen los mismos nombres. En controllers de components también podemos asignar nombres para definir cómo se debe de conocer al controlador dentro del HTML del componente, usando la propiedad "controllerAs":

.component('cuentaClics', {
  templateUrl: './components/cuenta-clics/cuenta-clics.html',
  controller: 'CuentaClicsController',
  controllerAs: 'vm'
});


Sin embargo en principio no necesitaríamos cambiar nunca ese nombre de controlador, ya que la arquitectura de componentes hace que los datos ofrecidos por un controlador estén encapsulados dentro de ese componente. Es decir, en componentes hijo no somos capaces de acceder a los datos de los controladores de los padres u otros antecesores y por ello no es necesario el cambio del nombre del controlador con "controllerAs".

Solo para aclarar posibles dudas cabe adelantar que el mecanismo para compartir datos de unos componentes a otros es el bindeo, enviando datos a los componentes hijos que los puedan necesitar. Esas técnicas de binding en componentes son las que vamos a tratar en el artículo siguiente.

En este HTML podrás encontrar el uso de la propiedad y método que habíamos definido en el controlador de nuestro componente cuentaClics.

<div>
  <h2>Cuenta Clics</h2>
  <p>Hasta el momento has hecho {{$ctrl.numClics}}</p>
  <button ng-click="$ctrl.incrementaClic()">Haz clic para incrementar el contador</button>
</div>

Usar un componente

En este momento asumimos que la mayoría conocerá el flujo para usar un componente como este, que hemos definido en un módulo independiente. Si es tu caso puedes saltarte esta sección, pero si estás comenzando con Angular o componentes quizás te vengan bien las siguientes pautas.

Nota: Nuestro componente es bueno colocarlo en un módulo independiente, donde solo esté este componente, para que podamos reutilizarlo fácilmente entre distintos proyectos, o incluso para que lo podamos compartir con otras personas.

1.- Definimos el componente, normalmente en una carpeta independiente donde estarán todos los ficheros. De momento tendremos el .js de la declaración del componente, en su módulo independiente, y el .html del template.

2.- Incluimos el script donde está el componente (el .js de la declaración). Esto lo podrás realizar de diversas formas, donde la más sencilla sería colocar la correspondiente etiqueta SCRIPT con el src hacia la ruta del componente.

<script src="components/cuenta-clics/cuenta-clics.js"></script>

3.- Al crear el módulo general de nuestra aplicación, definimos la dependencia con el módulo donde hemos creado nuestro component.

angular.module('miapp', [ 'cuentaClics'])

4.- Luego ya solo queda usar el componente, las veces que sean necesarias, usando la etiqueta correspondiente con el nombre del componente que hayamos creado. Solo ten en cuenta que si el nombre del componente en Javascript tiene notación "camel case", en el HTML tenemos que separar las palabras por guiones.

<cuenta-clics></cuenta-clics>

Eso es todo, tu componente debería funcionar sin problemas. Si no es así, revisa que la ruta en el src del script esté correcta, que el nombre del módulo donde está el component esté correcto, tenga notación camel case para separar palabras y que esté definida la dependencia en el módulo de tu aplicación. Revisa por último que la etiqueta HTML tiene separadas las palabras por guiones.

En la siguiente entrega de esta serie dedicada a componentes en Angular veremos algo muy interesante como es el binding entre componentes para facilitar la interoperabilidad.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual