Angular UI-Router 一种状态下的更多可选参数

IT技术 javascript angularjs angular-ui-router angular-ui
2021-03-06 09:23:09

如何在不使用查询字符串且仅使用一个路由名称的情况下允许我的路由使用可选参数?我目前正在指定每条路线五次以允许部件的任何组合:

所有部件都必须是可选的。路线必须解决任何变化。

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

必须有一种更简单/更清洁/不那么丑陋的方式。

4个回答

简短的回答....

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

一个工作plunker

这里的解决方案可能有两种类型。第一个真的非常有活力。第二个是根据需要工作,有点严格,但可以从UI-Router内置功能中受益

一、动态方法

让我们观察第一个,这很有趣(但在我们的场景中可能太复杂了)和这个问答很相似

递归 ui 路由器嵌套视图

我们尝试解决包含未知数量的文件夹*(目录)*名称网址

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

二、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 中表示默认参数值。如果未设置壁球,则使用配置的默认壁球策略。

这里检查它的行动

@pootzko 很高兴看到这一点,非常感谢您的回复;) 享受强大的 UI-Router
2021-04-20 09:23:09

另一种简单的方法是为参数设置一个默认值,如下所示:

params: {
  thing1: ""
}

根据 Angular UI Router docs,设置默认值会自动使参数成为可选的。

您可以使用ui-sref传递可选参数然后您可以使用 $stateParams 服务在您的控制器中访问它们。未通过的参数将保持为空。

.state("loginABCD", 
  { url: "/login/:a/:b/:c/:d",
    templateUrl: "login.html"
    controller: function($stateParams) {
      console.log($stateParams.a + $stateParams.b);
      }
  })
不幸的是,这种格式会阻止解析其他变体。例如,“/login”或“/login/123”不会解析为这种状态。
2021-04-30 09:23:09