Header Ads Widget

Ticker

6/recent/ticker-posts

Twitter Bootstrap Navbar como componente AngularJS

 Todos conocen Twitter Bootstrap , ¿no? Es la biblioteca increíble para hacer que su aplicación web se vea bastante bien sin pasar muchas horas en CSS. Estamos usando un diseño basado en Bootstrap en nuestro proyecto actual que también usa AngularJS y como estamos planeando tener muchas páginas nuevas, decidimos que cuanto antes introduzcamos algunos componentes en nuestra interfaz de usuario, mejor. Y, lo que no debería ser una sorpresa, la barra de navegación se convirtió naturalmente en el primer candidato.

Visión general

Entonces, en esta publicación, voy a mostrar cómo externalizar Twitter Bootstrap Navbar en un componente AngularJS flexible y separado. Todo el código fuente está disponible en mi repositorio de GitHub , por lo que todo debería ser fácil de seguir y repetir.

Configuración básica

Para empezar desde lo básico, he preparado tres páginas que utilizan la misma barra de navegación. Estas páginas pronto se convertirán en nuestra aplicación web súper simple usando AngularJS:

navbar_angularjs1

El siguiente paso será agregar AngularJS y convertir tres páginas en una pequeña aplicación. Esto se hace en este compromiso . Y después de eso, estamos listos para comenzar a trabajar en nuestro componente Navbar.

Problema

En cada página tenemos un elemento de barra de navegación de representación de fragmentos html muy similar.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<div class="navbar navbar-inverse">
    <div class="navbar-inner">
        <div class="container">
            <a class="brand">Example App</a>
 
            <div class="nav-collapse">
                <ul class="nav">
                    <li class="active"><a href="home.html">Home</a></li>
                    <li><a href="second.html">Second</a></li>
                    <li><a href="third.html">Third</a></li>
                </ul>
            </div>
        </div>
    </div>
</div>

La única diferencia está en dónde se encuentra la clase activa que resalta el enlace. Y cada vez que veamos tal repetición, nuestro detector DRY debería comenzar a sonar y no detenerse hasta que hagamos algo al respecto.

Directiva simple

Para empezar, trasladaremos este fragmento de código a una directiva AngularJS. Al principio, será solo un fragmento de código "tonto" que simplemente representa el mismo html en diferentes lugares. Todo el HTML de la lista anterior ahora se encuentra en el archivo components / bootstrapNavbar.html.

Lo siguiente que necesitamos es una declaración de directiva en el archivo JS:

1
2
3
4
5
6
7
8
9
angular.module('navbarapp', ['controllers'])
  .directive('bootstrapNavbar', function() { // (1)
  return {
    restrict: 'E',         // (2)
    replace: true,         // (3)
    transclude: true,      // (4)
    templateUrl: 'bootstrapNavbar.html'    // (5)
  }});
;

Qué pasa aquí:

  1. declaramos directiva, tenga en cuenta que el nombre de la directiva que use en el código será boostrap-navbar, camelCase se transforma en - carácter.
  2. restringir: E - significa que la directiva se usa como un elemento, hay otras opciones: clase C, atributo A, más sobre documentos
  3. reemplazar: verdadero: significa que el marcado de la plantilla reemplazará completamente el elemento de directiva en el marcado de la página
  4. transcluir: cierto - lo que significa ... será mejor que me lo digas, no puedo describirlo de manera más vaga que se hace en los documentos ;)
  5. templateUrl - archivo donde almacenamos el contenido de nuestra plantilla

Después de eso, deberíamos reemplazar el marcado html de la barra de navegación en cada página con algo como:

1
<bootstrap-navbar></bootstrap-navbar>

Ahora es el momento de probarlo. Desafortunadamente, existe un problema. La política de seguridad no permite que el navegador ejecute llamadas XHR (Ajax) desde un archivo html almacenado en nuestro disco. Así que tenemos que configurar httpServer ligero para entregar nuestros archivos al navegador. Puedes hacerlo usando Jetty o algo similar. Probé uno de Python y funcionó sin problemas. Entonces, básicamente, navegue al directorio donde se almacenan todos los archivos, ejecute:

1
python -m SimpleHTTPServer 9000

y luego abra su navegador usando la dirección http: // localhost: 9000 / home.html . Debería ver la misma página que antes, pero ahora usa nuestra directiva.

Flexibilidad ++

Así que tenemos nuestra primera directiva, ¡yay! Pero su coeficiente intelectual no es tan alto. Si navega a la segunda y tercera página, notará que siempre muestra el enlace a la página de inicio como activo, lo que no es exactamente cierto para todas las páginas. Y en este párrafo intentaremos hacerlo más inteligente.

Al principio, agreguemos el atributo current-tab a nuestros usos de directiva:

1
<bootstrap-navbar current-tab='Second'></bootstrap-navbar>

El valor pasado debe ser el mismo que el nombre del enlace en la barra de navegación, por lo que en nuestra aplicación de ejemplo debería ser: Inicio, Segundo o Tercero.

El siguiente paso es preparar nuestro archivo de plantilla para una fácil modificación. Debido a que usaremos selectores de jQuery para encontrar el enlace para activar, eliminaremos la clase activa y también agregaremos un atributo id al elemento ul para que sea más fácil de localizar con el selector:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<div class="navbar navbar-inverse">
    <div class="navbar-inner">
        <div class="container">
            <a class="brand">Example App</a>
 
            <div class="nav-collapse">
                <ul class="nav" id="navigation-tabs">     <!-- id added here -->
                    <li><a href="../home.html">Home</a></li>   <!-- removed class='active' -->
                    <li><a href="../second.html">Second</a></li>
                    <li><a href="../third.html">Third</a></li>
                </ul>
            </div>
        </div>
    </div>
</div>

Lógica central

Ahora lo último que tenemos que hacer es un poco de magia de selector de jQuery con poca adición de magia de AngularJS :)

Las directivas angulares tienen una función de compilación que permite alterar el marcado de la plantilla de directiva, por lo que la usaremos aquí. Lo que recibe esta función es el valor de los parámetros definidos en el uso del componente en nuestras páginas, por lo que básicamente tenemos acceso a todos los atributos que se declaran donde se usa nuestro componente de la barra de navegación, específicamente nuestro atributo de pestaña actual (nuevamente transformado a currentTab dentro del archivo JS ). Entonces, cuando sabemos qué enlace debe resaltarse, los selectores de jQuery vienen a hacer el trabajo real:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
angular.module('navbarapp', ['controllers'])
  .directive('bootstrapNavbar', function() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    templateUrl: 'components/bootstrapNavbar.html',
    compile: function(element, attrs) {  // (1)
      var li, liElements, links, index, length;
 
      liElements = $(element).find('#navigation-tabs li');   // (2)
      for (index = 0, length = liElements.length; index < length; index++) {
        li = liElements[index];
        links = $(li).find('a');  // (3)
        if (links[0].textContent === attrs.currentTab) $(li).addClass('active'); // (4)
      }
    }
  }});
;

Entonces, que hacemos aquí:

  1. define la función de compilación que ha pasado dos cosas, el elemento en el que se llama (marcado de plantilla en nuestro caso) y attrs, un objeto con todos los atributos declarados donde se usó nuestra directiva.
  2. seleccione todos los elementos de la lista del nodo # navigation-tabs
  3. encontrar todos los enlaces allí, será solo uno
  4. si el contenido de texto del enlace es igual al atributo currentTab, sabemos que este es el enlace para resaltar, por lo que simplemente agregamos la clase CSS adecuada allí

Es la solución de trabajo más sencilla. Por supuesto, podríamos agregar alguna verificación de errores, pero quería mostrar un enfoque fácil de seguir para introducir componentes flexibles en las aplicaciones AngularJS.

Resumen

En esta publicación intenté mostrar cómo con unos simples pasos podríamos aplicar la regla DRY a nuestro marcado html en la aplicación AngularJS. Y a medida que su aplicación crezca, probablemente encontrará más y más lugares donde html se duplica, lo que lo convierte en un buen candidato para convertirlo en directiva de componentes.

Publicar un comentario

0 Comentarios