9

I have a similar route that should load a different view and controller based on whether or not the parameter is a number. Example:

  • /artists/2 should ArtistsIndexController with a view /www/artists/index.html
  • /artists/name should ArtistsProfileController with a view /www/artists/profile.html

Ideally I would use something like:

$routeProvider.when("/artists/:page", {
  templateUrl: "/www/artists/index.html",
  controller: "ArtistsIndexController"
});

$routeProvider.when("/artists/:name", {
  templateUrl: "/www/artists/profile.html",
  controller: "ArtistsProfileController"
});

Where :page is a number and :name is not.

Note I see a related github issue (found from this question) but am wondering if there is a resolution or preferred solution.

Community
  • 1
  • 1
Gloopy
  • 37,767
  • 15
  • 103
  • 71

3 Answers3

4

Another way is to use the ui-router which supports regular expressions for routes (among a slew of other things) which would allow:

$stateProvider.state("artists-index", {
  url: "/artists/{page:[0-9]*}",
  templateUrl: "/www/artists/index.html",
  controller: "ArtistsIndexController"
});

$stateProvider.state("artists-profile", {
  url: "/artists/{name}",
  templateUrl: "/www/artists/profile.html",
  controller: "ArtistsProfileController"
});
Gloopy
  • 37,767
  • 15
  • 103
  • 71
  • what is difference between route & state? – Apul Gupta Sep 04 '15 at 12:17
  • @Apul when I've used ui-router I've always had a route for each state so I just thought of the states as a route. The [docs](https://github.com/angular-ui/ui-router) mention that not every state needs a route but I wouldn't worry about that at first. You can look at [this](https://en.wikipedia.org/wiki/Finite-state_machine) for more details on the concept of a generic state machine as well. – Gloopy Sep 04 '15 at 13:56
3

I use a nasty hack, that consist on change the regexp

var $route = $routeProvider.$get[$routeProvider.$get.length-1]({$on:function(){}});


$routeProvider.when("/artists/:page", {
  templateUrl: "/www/artists/index.html",
  controller: "ArtistsIndexController"
});

$routeProvider.when("/artists/:name", {
  templateUrl: "/www/artists/profile.html",
  controller: "ArtistsProfileController"
});

$route.routes['/artist/:page'].regexp = /^\/(?:artist\/(\d+))$/
$route.routes['/artist/:page/'].regexp = /^\/(?:artist\/(\d+))\/$/

It's ugly but it works fine. You can change your routes' regexps to make them match whatever you want.

pykiss
  • 949
  • 12
  • 15
1

I'm using this as a solution for now and would be interested in alternatives!

1) Create a generic template that will load in a controller and view dynamically:

<div ng-controller="controller" ng-include src="templateUrl"></div>

In this example I placed this view in /www/shared/dynamic-controller.html

2) Create a controller that checks the route params to determine which controller and view to load:

angular.module('appName').
  controller('ArtistsDynamicRouteController', ['$scope', '$controller', '$routeParams', function($scope, $controller, $routeParams) {
    if(/^\d+$/.test($routeParams.pageOrId)) {
      // when pageOrId is a page (number) we want to load the ArtistsIndexController
      $scope.controller = $controller('ArtistsIndexController', { $scope: $scope }).constructor;
      $scope.templateUrl = '/www/artists/index.html';
    } else {
      // when pageOrId is an id (non-number) we want to load the ArtistsProfileController
      $scope.controller = $controller('ArtistsProfileController', { $scope: $scope }).constructor;
      $scope.templateUrl = '/www/artists/profile.html';
    }
  }]);

3) Use one route regardless of the parameter type:

// handles both /artists/2 and /artists/username
$routeProvider.when("/artists/:pageOrName", {
  templateUrl: "/www/shared/dynamic-controller.html",
  controller: "ArtistsDynamicRouteController"
});
Gloopy
  • 37,767
  • 15
  • 103
  • 71
  • 1
    See [this question](http://stackoverflow.com/questions/18137810/how-to-eliminate-minification-errors-when-using-controller-in-angularjs) for issues with minification when doing this. – Gloopy Aug 09 '13 at 17:23