2013-08-08 2 views
9

Ich habe eine ähnliche Route, die eine andere Ansicht und Controller basierend darauf, ob der Parameter eine Zahl ist oder nicht, laden soll. Beispiel:AngularJS Regex Route für ähnliche URL zum Laden unterschiedlicher Controller und Ansicht

  • /artists/2 sollte ArtistsIndexController mit Blick /www/artists/index.html
  • /artists/name sollte ArtistsProfileController mit Blick /www/artists/profile.html

Idealerweise würde ich so etwas wie verwenden:

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

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

Wo :page eine Zahl und :name ist nicht.

Hinweis Ich sehe eine verwandte github issue (gefunden von this question), aber ich frage mich, ob es eine Lösung oder bevorzugte Lösung gibt.

Antwort

1

Ich benutze dies als eine Lösung für jetzt und wäre an Alternativen interessiert!

1) Erstellen Sie eine generische Vorlage, die in einem Controller geladen werden kann und sehen dynamisch:

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

In diesem Beispiel stellte ich diese Ansicht in /www/shared/dynamic-controller.html

2) Erstellen Sie einen Controller, der die Route params überprüft

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) Verwenden einer Route, unabhängig von der Art der Parameter: zu laden, die Controller und anzuzeigen, um zu bestimmen

// handles both /artists/2 and /artists/username 
$routeProvider.when("/artists/:pageOrName", { 
    templateUrl: "/www/shared/dynamic-controller.html", 
    controller: "ArtistsDynamicRouteController" 
}); 
+1

Siehe [diese Frage] (http://stackoverflow.com/questions/18137810/how-to-eliminate-minification-errors-when-using-controller-in-angularjs) für Probleme mit der Verkleinerung, wenn Sie dies tun. – Gloopy

4

Eine andere Möglichkeit ist es, die ui-router zu verwenden, die für Routen von regulären Ausdrücken unterstützt (unter einer Reihe von anderen Dingen), die erlauben würde:

$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" 
}); 
+0

Was ist der Unterschied zwischen Route und Status? –

+0

@Apul, wenn ich UI-Router verwendet habe Ich hatte immer eine Route für jeden Staat so dachte ich nur an die Staaten als Route. Die [Docs] (https://github.com/angular-ui/ui-router) erwähnen, dass nicht jeder Staat eine Route braucht, aber ich würde mir darüber zunächst keine Sorgen machen. Sie können sich [this] (https://en.wikipedia.org/wiki/Finite-state_machine) für weitere Details zum Konzept einer generischen Zustandsmaschine ansehen. – Gloopy

3

ich ein gemeiner Hack verwenden, die auf Änderung bestehen die 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+))\/$/ 

Es ist hässlich, aber es funktioniert gut. Sie können die Regexs Ihrer Routen so ändern, dass sie Ihren Vorstellungen entsprechen.

+0

Vielen Dank, es ist sehr hilfreich für mich :) – imbolc