Angular UI-Router больше Необязательные параметры в одном государстве

Как разрешить дополнительные параметры для моих маршрутов без использования строки запроса и только с использованием одного имени маршрута? В настоящее время я указываю каждый маршрут FIVE TIMES, чтобы разрешить любую комбинацию частей:

Все детали должны быть необязательными. Маршрут должен разрешить любые варианты.

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

Там ДОЛЖЕН быть более простым/чистым/менее уродливым способом.

Ответы

Ответ 1

Короткий ответ....

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

Ответ 2

Существует рабочий плункер

Решение здесь может быть двух типов. Первый действительно очень динамичный. Второй работает по мере необходимости, немного более жестко, но извлекает выгоду из встроенных функций UI-Router.

I. Динамический подход

Посмотрим на первое, что интересно (но, может быть, слишком сложное в нашем сценарии). Он очень похож на это Q и A

Рекурсивные вложенные представления маршрутизатора ui

Мы пытаемся решить url, который содержит неизвестное количество папок * (каталогов) * имен:

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

Состояние может быть определено следующим образом:

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

И это приведет к одному параметру folderPath с полным пути к папке.

В случае, если мы хотели бы решить наш сценарий (обрабатываем ровно три параметра), мы могли бы расширять такие вещи как

Контроллер для обработки файлов:

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

Определение состояния с помощью распознавателя:

// 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. Встроенная функция UI-Router params : {}

Второй сценарий, на самом деле, очень прост. Он использует встроенную функцию UI-Router: params : {}. Проверьте его документацию здесь:

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

Это будет наше определение состояния:

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

И все эти ссылки будут работать:

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

И какой был трюк:

squash - {bool|string=}: squash настраивает, как значение параметра по умолчанию отображается в URL, когда текущее значение параметра совпадает с значением по умолчанию. Если сквош не установлен, он использует настроенную политику сквоша по умолчанию.

Проверьте действие здесь

Ответ 3

Еще один простой способ сделать это - просто установить значение по умолчанию для параметра, например:

params: {
  thing1: ""
}

В соответствии с Angular Документами UI Router установка значения по умолчанию автоматически делает параметр необязательным.

Ответ 4

Вы можете передать необязательные параметры, используя ui-sref. Затем вы можете получить доступ к ним в своем контроллере, используя службу $stateParams. Параметры, которые не передаются, просто останутся пустыми.

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