web-dev-qa-db-fra.com

Angular UI-Router plus de paramètres facultatifs dans un état

Comment puis-je autoriser des paramètres facultatifs à mes itinéraires sans utiliser une chaîne de requête et en utilisant un seul nom d'itinéraire? Je spécifie actuellement chaque itinéraire CINQ FOIS pour permettre toute combinaison de pièces:

Toutes les pièces doivent être facultatives. L'itinéraire doit résoudre toute variation.

.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" })

Il DOIT y avoir un moyen plus facile/plus propre/moins laid.

21
G. Deward

Réponse courte....

.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 },
    }
})
39
Fred Lackey

Il y a n plongeur qui travaille

La solution ici pourrait être de deux types. Le premier est vraiment très dynamique. Le second fonctionne au besoin, un peu plus rigide, mais bénéficiant de UI-Router fonctionnalités intégrées.

I. Approche dynamique

Observons le premier, qui est intéressant (mais peut-être trop compliqué dans notre scénario). Il est très similaire à ce Q & A

vues imbriquées du routeur ui récursif

Nous essayons de résoudre le url qui contient une quantité inconnue de dossiers * (répertoires) * noms:

<a href="#/files/Folder1">
<a href="#/files/Folder1/SubFolder1/">
<a href="#/files/Folder1/SubFolder1/SubFolderA">

L'état pourrait être défini comme ceci:

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

Et cela conduira à un paramètre folderPath avec le chemin complet du dossier.

Dans le cas où nous voudrions résoudre notre scénario (gérer exactement trois paramètres) nous pourrions étendre des trucs comme ça

Contrôleur pour la gestion des fichiers:

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

Définition d'état à l'aide du résolveur:

// 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. Fonction intégrée UI-Router params : {}

Le deuxième scénario est en fait très très simple. Il utilise UI-Router fonction intégrée: params : {}. Consultez sa documentation ici:

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

Ce serait notre définition de l'État:

.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},
    }
})

Et tous ces liens fonctionneront également:

<a href="#/login">
<a href="#/login/ValueA">
<a href="#/login/ValueA/ValueB">
<a href="#/login/ValueA/ValueB/ValueC">

Et quel était le truc:

squash - {bool|string=}: squash configure la façon dont une valeur de paramètre par défaut est représentée dans l'URL lorsque la valeur de paramètre actuelle est identique à la valeur par défaut. Si squash n'est pas défini, il utilise la stratégie de squash par défaut configurée.

Vérifiez-le action ici

21
Radim Köhler

Une autre façon simple de le faire est de simplement définir une valeur par défaut pour le paramètre, comme ceci:

params: {
  thing1: ""
}

Selon le Angular I Router docs , la définition d'une valeur par défaut rend automatiquement le paramètre facultatif.

2
Nick A. Watts