Angolare UI-Router più parametri opzionali in uno stato

Come posso consentire i parametri opzionali ai miei percorsi senza utilizzare una stringa di query e utilizzando solo un nome di percorso? Attualmente sto specificando ciascuna rotta CINQUE VOLTE per consentire qualsiasi combinazione di parti:

Tutte le parti devono essere opzionali. La rotta deve risolvere qualsiasi variazione.

.state("login", { url: "/login", templateUrl: "login.html", params: { a: null, b: null, c: null, d: null } }) .state("loginA", { url: "/login/:a", templateUrl: "login.html", params: { b: null, c: null, d: null } }) .state("loginAB", { url: "/login/:a/:b", templateUrl: "login.html", params: { c: null, d: null } }) .state("loginABC", { url: "/login/:a/:b/:c", templateUrl: "login.html", params: { d: null } }) .state("loginABCD", { url: "/login/:a/:b/:c/:d", templateUrl: "login.html" }) 

Deve esserci un modo più semplice / pulito / meno brutto.

Risposta breve….

 .state('login', { url: '/login/:a/:b/:c/:d', templateUrl: 'views/login.html', controller: 'LoginCtrl', params: { a: { squash: true, value: null }, b: { squash: true, value: null }, c: { squash: true, value: null }, d: { squash: true, value: null }, } }) 

C’è un plunker funzionante

La soluzione qui potrebbe essere di due tipi. Il primo è davvero molto dinamico. Il secondo funziona come necessario, un po ‘più rigido, ma traendo profitto dalle funzionalità integrate del UI-Router .

I. Approccio dinamico

Osserviamo il primo, che è interessante (ma forse troppo complicato nel nostro scenario) . È molto simile a questo Q & A

Visualizzazioni nidificate del router ui ricorsivo

Cerchiamo di risolvere l’ url che contiene una quantità sconosciuta di cartelle * (directory) * nomi:

    

Lo stato potrebbe essere definito in questo modo:

 .state('files', { url: '/files/{folderPath:[a-zA-Z0-9/]*}', templateUrl: 'tpl.files.html', ... 

E questo porterà a un parametro folderPath con il percorso completo della cartella.

Nel caso in cui vorremmo risolvere il nostro scenario (gestire esattamente tre parametri) potremmo estendere cose come questa

Controller per la gestione dei file:

 .controller('FileCtrl', function($scope, a, b, c) { $scope.paramA = a; $scope.paramB = b; $scope.paramC = c; }) 

Definizione dello stato usando il resolver:

 // helper method var findParams = function($stateParams, position) { var parts = $stateParams.folderPath.split('/') var result = parts.length >= position ? parts[position] : null; return result; } ... // state calls resolver to parse params and pass them into controller .state('files', { url: '/files/{folderPath:[a-zA-Z0-9/]*}', templateUrl: 'tpl.files.html', controller: 'FileCtrl', resolve: { a : ['$stateParams', function($stateParams) {return findParams($stateParams, 0)}], b : ['$stateParams', function($stateParams) {return findParams($stateParams, 1)}], c : ['$stateParams', function($stateParams) {return findParams($stateParams, 2)}], } }) 

II. Parametri della funzione incorporata nell’interfaccia utente params : {}

Il secondo scenario, infatti, è molto semplice. Utilizza la UI-Router incorporata UI-Router : params : {} . Controlla la sua documentazione qui:

http://angular-ui.github.io/ui-router/site/#/api/ui.router.state . $ stateProvider

Questa sarebbe la nostra definizione di stato:

 .state('login', { url: '/login/:a/:b/:c', templateUrl: 'tpl.login.html', controller: 'LoginCtrl', params: { a: {squash: true, value: null}, b: {squash: true, value: null}, c: {squash: true, value: null}, } }) 

E tutti questi link funzioneranno pure:

     

E qual è il trucco:

squash{bool|string=} : squash configura come un valore di parametro predefinito viene rappresentato nell’URL quando il valore del parametro corrente è uguale al valore predefinito. Se Squash non è impostato, utilizza il criterio di squash predefinito configurato.

Controlla qui in azione

Un altro modo semplice per farlo è semplicemente impostare un valore predefinito per il parametro, in questo modo:

 params: { thing1: "" } 

Secondo i documenti del router UI angular, l’impostazione di un valore predefinito rende automaticamente il parametro facoltativo.

È ansible passare parametri facoltativi usando ui-sref . È quindi ansible accedervi dal controller utilizzando il servizio $ stateParams. I parametri che non vengono passati resterebbero nulli.

 .state("loginABCD", { url: "/login/:a/:b/:c/:d", templateUrl: "login.html" controller: function($stateParams) { console.log($stateParams.a + $stateParams.b); } })