Primeros pasos con angular-ui-router

Ejemplo de Hola Mundo

PASO 1: Instalación

Antes de que pueda usar Angular-UI Router, debe incluir AngularJS en su proyecto. Para obtener una guía detallada al respecto, consulte esta documentación.

Puede descargar Angular-UI Router desde su GitHub-Page o desde NuGet, NPM, Bower respectivamente.

Después de haber incluido el archivo JS en su página web, puede inyectar el módulo ui.router dentro de su aplicación. En tu archivo de script deberías tener algo como esto:

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

y ahora vamos a inyectar Angular-UI Router en nuestra propia aplicación de esta manera:

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

Ahora Angular-UI Router se cargará con nuestra aplicación. Los siguientes pasos explicarán los conceptos básicos detrás de Angular-UI Router y mostrarán algunas de las funciones básicas.


PASO 2: Definición de estados simples

Puede configurar el UI-Router dentro de la función config de Angular. Usa $stateProvider para definir tus estados. En el siguiente ejemplo, cada estado tiene una URL, un controlador y una plantilla.

(function() {
  var app = angular.module('app', ['ui.router']);
  
  app.config(['$stateProvider', function($stateProvider) {
      $stateProvider
        .state('home', {
          url: "/home",
          templateUrl: "home.html",
          controller: "homeCtrl"
        })
        .state('kitchen', {
          url: "/kitchen",
          templateUrl: "kitchen.html",
          controller: "kitchenCtrl"
        })
        .state('den', {
          url: "/denCtrl",
          templateUrl: "den.html",
          controller: "denCtrl"
        })
        .state('itemDetail', {
          url: "/items/:itemName",
          templateUrl: "item.html",
          controller: "itemDetailCtrl"
        })

    }])
})();

en su HTML, necesitará la directiva ui-view para que las vistas de estado se puedan completar en el interior.

<div ui-view></div>

PASO 3: Acceder a los estados

Hay en total 3 formas de acceder a un estado que se define en $ stateProvider.

1. A través de la directiva ui-sref

Puede acceder a los estados dentro de su HTML usando la directiva ui-sref

<li ui-sref-active="active">
    <a ui-sref="kitchen">Go to the Kitchen</a>
</li>
<li ui-sref-active="active">
    <a ui-sref="den">Enter the den</a>
</li>
<li ui-sref-active="active">
    <a ui-sref="itemDetail({itemName:'keyboard'})">Key Board</a>
</li>

2. Mediante el servicio $state en el controlador

también puede navegar a otros estados dentro de su controlador usando el $estado proporcionado al controlador con el método .go.

.controller(function($scope, $state) {
    // ...
    $scope.navigateTo = function(stateName) {
        $state.go(stateName); // i.e. $state.go('den'); 
    };
})

3. A través de la URL en el navegador

Asumiendo que tienes un estado llamado cocina definido así:

$stateProvider
  .state("kitchen", {
    url: "/kitchenUrl",
    ...
  });

Luego, al acceder a appdomain/kitchenUrl como la URL en su navegador, irá a su estado de cocina, asumiendo que no hay estados anidados y appdomain es el servidor que aloja su aplicación.

Si todavía está confundido, aquí hay un Plnkr que funciona completamente

Vista básica

índice.html

<html>
    <head>
        <title>Angular-UI Router Example</title>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
        <script type="text/javascript" src="../js/script.js"></script>
    </head>
    <body ui-view="mainView"> <!-- Defining a container for our view -->
    </body>
</html>

guión.js

var app = angular.module('app', ['ui.router']);
app.config(['$stateProvider', function($stateProvider){
    $stateProvider.state('home', {                        // Creating a state called 'home'
        url: '',                                          // An empty URL means that this state will be loaded on the main URL when no other state is called
        views: {
            'mainView': {                                 // Section for our view-container that we defined in the HTML
                template: '<h1>It works!</h1>'            // Setting a template for this view
                /*templateUrl: '../templates/home.html'*/ //templateUrl would load the file and uses it's content as the template
             }
        }
    });
}])

Definición de un estado con vista múltiple

En ui-router, un estado puede contener múltiples vistas, cada una con su propio controlador y una plantilla

.state('dashboard', {
     name: 'dashboard',
     url: '/dashboard',
     views: {
         "view1": {
             templateUrl: "path/to/view1.html",
             controller: "view1Controller"
         },
         "view2": {
             templateUrl: "path/to/view2.html",
             controller: "view2Controller"
         }
     }
 })

Luego, dentro del HTML de su estado, puede vincular estas vistas

<div ui-view="view1"></div>
<div ui-view="view2"></div>

Resolver datos en un estado

Puede “resolver” los datos en su estado cuando hace la transición a él, por lo general, es útil cuando el estado necesita usar esos datos, o para resolver en un estado cuando alguna entrada proporcionada necesita ser autenticada.

Cuando defina sus estados, deberá proporcionar un mapa de valores para resolver en la propiedad .resolve, cada valor resuelto debe tener una función que devuelva una promesa

.state('main', {
     url: "/main",
     templateUrl: "path/to/main.html",
     controller: 'mainCtrl',
     resolve: {
         serverData: function ($http) {
             return $http.get('some/url');
         }
     }
});

Ahora, dentro de mainCtrl puede acceder a los datos (es decir, si la llamada $http se resolvió correctamente).

.controller("mainCtrl", function($scope, serverData) {
    $scope.resolvedData = serverData.then(resp=> resp.data);
    ....
})

Usar eventos de transición

UI-Router expone eventos de transición que pueden ser útiles para manejar errores de transición, manejar/bloquear transiciones basadas en ciertos valores de parámetros, autenticación personalizada, etc.

Estos eventos se pueden vincular a $rootScope para un efecto global o a $scope para un efecto por controlador.


$stateChangeError: este evento se transmite cuando un intento de cambiar el estado ha fallado y se ha producido un error. Este evento activa una función de devolución de llamada con la siguiente firma:

devolución de llamada(evento, estado, parámetros, estado, parámetros, error)

evento: el objeto del evento

toState: el estado objetivo

toParams: los parámetros pasados ​​al estado de destino

fromState: estado actual

fromParams: los parámetros pasados ​​al estado actual

error: el objeto de error


$stateChangeStart: este evento se transmite cuando se inicia una transición de estado, este evento activa una función de devolución de llamada con la siguiente firma:

devolución de llamada (evento, estado, parámetros, estado, parámetros, opciones)

opciones: el objeto de opciones de estado

$stateChangeSuccess: este evento se transmite cuando se completa una transición de estado, este evento activa una función de devolución de llamada con la siguiente firma:

devolución de llamada (evento, estado, parámetros, estado, parámetros, opciones)


$stateNotFound: este evento se transmite cuando no se encuentra un estado al que solicitó la transición, este evento activa una función de devolución de llamada con la siguiente firma:

devolución de llamada (evento, unfoundState, fromParams, fromState)

unfoundState: un objeto que representa el estado que no se encontró


Ejemplo:

$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams, options) {
    $log.debug("$stateChangeSuccess: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, options: %o", event, toState, toParams, fromState, fromParams, options);
    // runs when the state has successfully changed
});

$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
    $log.debug("$stateChangeStart: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, options: %o", event, toState, toParams, fromState, fromParams, options);
    // runs when the state has just started to transition
});

$rootScope.$on('$stateNotFound', function (event, unfoundState, fromParams, fromState) {
    $log.debug("$stateNotFound: event: %o unfoundState: %o, fromParams: %o, fromState: %o", event, unfoundState, fromParams, fromState);
    // runs when the state wsa not found
});

$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
    $log.debug("$stateChangeError: event: %o toState: %o, toParams: %o, fromState: %o, fromParams: %o, error: %o", event, toState, toParams, fromState, fromParams, error);
    // runs when there was an error while attempting to transition
});