$routeProvider define las rutas mediante sus dos métodos como veíamos anteriormente:
Cuando encuentra una url entonces aplica la ruta...
path es la url que se muestra en el navegador web. Al ser una ruta single-page tenemos que se muestra mediante hashtag # en plan www.miapp.com/#/pagina1.
route es el objeto ruta que tiene ciertas [propiedades] (https://docs.angularjs.org/api/ngRoute/provider/$routeProvider) entre las que destacamos:
templateUrl. Url de la plantilla / vista HTML que va a cargar. Devuelve el HTML que será cargado en ng-view o en directivas ng-includes. Existe también el parámetro template donde se pone el código HTML en el momento pero por escalabilidad es preferible utilizzar templateUrl,
controller. Nombre del controlador que va a ejecutar o incluso se puede definir la función del controlador al instante (no recomendable). De esta manera indica, para esta ruta carga la vista de templateURL con el controlador indicado.
También existe el parámetro controllerAs (alias del controlador) que hace que el controlador sea publicado en el scope (ámbito) con ese nombre alias.
redirectTo. Permite redireccionar a otra ruta. path or function that returns a path to an html template that should be used by ngView.
[reloadOnSearch=true]. Recarga la ruta cuando hay cambios en la url, en $location. Valor por defecto a true, es decir, recargar la ruta.
[caseInsensitiveMatch=false]. Evalua si es keysensitive o no. Valor por defecto false, es decir, tiene en cuenta las mayúsculas y las minúsculas.
Las rutas se leen en cascada una debajo de la otra. Si ninguna ruta coincide entonces se ejecuta el
método otherwise. otherwise( {redirectTo: '/'});
De manera que si se pone cualquier url en la barra de navegación la app hará un redirect hacia la ruta raíz (en este caso).
Ejemplo routing
var uazonApp = angular.module("uazonApp",['ngRoute','libros'])
.config(
function($routeProvider)
{
$routeProvider
.when('/listado',
{
templateUrl:'src/views/listado.html',
controller: 'LibrosCtrl'
})
.when('/nuevo-libro',
{
templateUrl:'src/views/nuevo-libro.html',
controller: 'LibrosFichaCtrl'
})
.otherwise( {redirectTo: '/listado'});
}
);
$routeParams nos permite recoger parámetros de la url. Requiere el módulo ngRoute también.
Para ello en la ruta lo definimos mediante dos puntos y el nombre del parámetro :libroId
var uazonApp = angular.module("uazonApp",['ngRoute','libros'])
.config(
function($routeProvider)
{
$routeProvider
.when('/ficha-libro/:libroId',
{
templateUrl:'src/views/ficha-libro.html',
controller: 'LibrosFichaCtrl'
})
}
);
En el controlador la forma de recuperar ls parámetros $routeParams es inyectando $routeParams:
angular.controller("LibrosFichaCtrl",['$scope','$routeParams',function($scope,$routeParams) {
$scope.libroId = $routeParams.libroId;
}]);
Si queremos evitar el # podemos activar el modo HTML5 en las rutas evitando así el refresco de página. Para este cometido tendremos que realizar dos tareas:
$locationProvider.html5Mode(true);
var miApp = angular.module("miApp",['ngRoute'])
.config(
function($routeProvider, $locationProvider)
{
$routeProvider
.when('/pagina1',
{
templateUrl:'paginas/pagina1.html',
})
.when('/pagina2',
{
templateUrl:'paginas/pagina2.html',
})
.otherwise( {redirectTo: '/pagina1'});
//elimina # de la navegación
$locationProvider.html5Mode(true);
}
);
<base href="/">
<html ng-app="miApp">
<head>
<base href="/">
</head>
<body>
...
</body>
</html>
Un detalle importante es que aplicando estas dos tareas embelleceremos nuestras urls pero si copiamos la URL y la pegamos en otra ventana del navegador la aplicación no funcionará porque el servidor (en este caso Apache) pensará que es una ruta URL normal.
Por ejemplo midominio.com/pagina1
da un error de página no encontrada. Sin embargo si introducimos midominio.com/#/pagina1
si se accede a la aplicación y AngularJS modifica la URL dejándola en la deseada midominio.com/pagina1
Por eso para conseguir que incluso la URL sin # funcione al copiar y pegar esta URL en un navegador hay que hacer un pequeño hack en la configuración del.htaccess de Apache de manera que cuando llegue una URL nueva siempre siempre se sustituya por la URL con hashtag # que AngularJS la entienda y así pueda ser la propia aplicación la que le quite de nuevo el # embellecendo perfectamente la dirección URL.
.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) /index.html/#/$1
</IfModule>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) /#/$1 [R=301,NE,L]