Table des matières

ngRoute

On peut également utiliser ui-router.

Utilise <ng-view></ng-view>.

Dans un fichier routing.js ou app.js, on peut configurer les routes.

angular.module('myApp', ['ngResource'])
  .config(function($routeProvider) {
    $routeProvider.when('/newEvent', {
      templateUrl: 'templates/NewEvent.html',
      controller: 'EventEditController'
    });
    $routeProvider.when('/events', {
      templateUrl: 'templates/EventList.html',
      controller: 'EventListController'
    });
    $routeProvider.when('/event/:eventId', {
      templateUrl: 'templates/EventDetails.html',
      controller: 'EventController'
    });
  });

Dans le fichier HTML qui appelle le template (ex: index.html), les liens ressemblent à :

<a href="#/newEvent">New Event</a>

Le # est nécessaire dans le mode par défaut. Il faut utiliser le mode HTML5 pour s'en débarrasser.

Route par défaut

$routeProvider.otherwise({redirectTo: '/events'});

$routeParams

Les paramètres passés dans les routes sont disponibles dans $routeParams. Si on reprend la route /event/:eventId :

$routeProvider.when('/event/:eventId', {
  templateUrl: 'templates/EventDetails.html',
  controller: 'EventController'
});

Le paramètre eventId est passé de l'URL. Disons qu'on a localhost:8080/event/2, eventId aura la valeur 2.

Dans le contrôleur EventController, on peut donc s'en servir, ce sera une propriété de $routeParams du même nom :

angular.module('myApp').controller('EventController',
  function ($scope, eventData, $routeParams) {
    $scope.event = eventData.getEvent($routeParams.eventId);
  }

$route

Si on reprend la route et on y ajout la propriété foo :

$routeProvider.when('/event/:eventId', {
  foo: 'bar',
  templateUrl: 'templates/EventDetails.html',
  controller: 'EventController'
});

Dans le contrôleur:

angular.module('myApp').controller('EventController',
  function ($scope, eventData, $route) {
    console.log($route.current.foo);
  }

Le code ci-haut affiche bar dans la console.

Query String

Si on accède la page par l'URL localhost:8080/event/1?foo=bar, on peut avoir le paramètre foo avec :

console.log($route.current.params.foo);  // retourne 'bar'
console.log($route.current.params.eventId);  // retourne '1'

On peut utiliser aussi $route.current.pathParams.eventId car il est spécifié dans la route /event/:eventId, mais on ne pourrait pas utiliser $route.current.pathParams.foo même s'il est en querystring dans l'URL, parce qu'il ne fait pas partie de la route justement.

reload()

On peut recharger la vue de la route, sans recharger la page au complet.

$route.reload();

HTML 5 Routing

Il suffit d'injecter $locationProvider et utiliser:

$locationProvider.html5mode(true);

Template

Dans les routes, on peut spécifier directement template au lieu de templateUrl, comme ce fût utilisé auparavant. Le principal avantage de ça, c'est de pouvoir générer des templates sur le volet, à l'aide d'un service par exemple.

$routeProvider.when('/event/:eventId', {
  template: '<h1>Allo Monde.</h1>',
  controller: 'EventController'
});

Ou bien :

$routeProvider.when('/event/:eventId', {
  template: templateService.generateTemplate(),
  controller: 'EventController'
});

Resolve

Si un certain travail doit être fait avant d'afficher le template, comme par exemple la récupération de données, on peut utiliser resolve. Quand ce qui est assigné à resolve sera résolvé, le template s'affiche.

Dans l'exemple suivant, on veut que les données de l'événement soient disponibles avant l'affichage du template EventDetails.html.

$routeProvider.when('/event/:eventId', {
  templateUrl: 'templates/EventDetails.html',
  controller: 'EventController',
  resolve: {
    event: function($q, $route, $eventData) {
      var deferred = $q.defer();
      eventData.getEvent($route.current.pathParams.eventId).then(function(event) {
        deferred.resolve(event);
      });
      return deferred.promise;
    }
  }
});

Dans le contrôleur (dans notre cas EventController), on n'utilise plus le eventData, mais les données récupérés par le resolve :

var $scope.event = $route.current.locals.event;

$location

Au lieu d'utiliser des liens <a href="/newEvent"></a>, on peut utiliser $location.url(), dans une fonction par exemple appelée d'un bouton :

<button class="btn" ng-click="createEvent()">Créer un événement</button>

Dans le contrôleur:

$scope.createEvent = function() {
  $location.url('/newEvent');
};

Ayant l'URL suivant dans le navigateur http://localhost:8080/newEvent?foo=bar&eventId=2#qux, voici

Propriété Appel Exemple de retour
absUrl $location.absUrl() http://localhost:8080/newEvent
protocol $location.protocol() http
port $location.port() 8080
host $location.host() localhost
path $location.path() /newEvent
search $location.search() Object {fooL "bar", eventId: "2"}
hash $location.hash() qux
url $location.url() /newEvent?foo=bar&eventId=2#qux

Les méthodes path(), search(), hash() et url() sont des méthodes que l'on peut lire les données (getter) et assigner la donnée (setter). Les autres sont seulement des getters.

replace()

Permet de faire une nouvelle page sans faire une nouvelle page (ouin, c'est ça). Ceci a pour effet par exemple, de supprimer l'historique du navigateur, comme si on avait fait un nouvel onglet et navigué à un certain URL, il n'y a pas d'historique associé à ce nouvel onglet.