ui.router:为什么导航到其子状态时,父状态的 url 参数为空

ui.router: why is url parameter empty for a parent state when navigating to its child

我试图在导航到其子状态时在父状态获取 url 参数,但在父状态级别,url 参数作为空字符串返回 "".

这是我的状态配置定义:

$stateProvider
  .state("view", {
    url: "/{viewName}",
    controller: function($scope, $stateParams){
      $scope.viewName = $stateParams.viewName;
    },
    template: "<pre>viewName: {{viewName}}</pre> <div ui-view></div>",
  })
  .state("view.A", {
    url: "^/viewA/{id}",
    template: "<div>content of A</div>"
  })
  .state("view.B", {
    url: "^/viewB/{id}",
    template: "<div>content of B</div>"
  });

(满plunker)

示例 url 是:

#/viewA/111
#/viewA/222
#/viewB/555

我想要获取的是来自父级 URL(例如 "viewA")的视图名称。

问: 是否可以不求助于 URL 正则表达式?

编辑:

需要注意的一个重要要求是能够使用 ui-sref$state.go:

导航到子状态
<a ui-sref="view.A({id: 1})">

并相应地更改 URL。此要求阻止了子状态的相对 urls 的方法:

.state("view.A", {
    url: "/{id}", // relative URL
    template: "<div>content of A</div>"
  })

要解决上述情况,可以在每个 child:

的自定义数据字段中定义 viewName
.state("view.A", {
  url: "/viewA/{id}",
  template: "<div>content of A</div>",
  data: {
    viewName: "viewA"
  }
})
.state("view.B", {
  url: "/viewB/{id}",
  template: "<div>content of B</div>",
  data: {
    viewName: "viewB"
  }
});

并使用 $state 变量到 $watch 来更改 $state.$current.data:

.state("view", {
  controller: function($scope, $state){
    $scope.$state = $state; // need to watch $state, not $state.$current
    $scope.$watch("$state.$current.data.viewName", function(val){
      $scope.viewName = val;
    });
  },
  template: "<pre>viewName: {{viewName}}</pre> <div ui-view></div>",
});

请注意,您不能只获取或监视 $state.$current.data.viewName,因为 parent 的控制器仅针对其后代之间的任何状态变化运行一次。

plunker

使用 $stateParams 有意义吗?

parent状态的URL参数没有定义,估计是因为child状态使用的是绝对的URL,所以,URL parent 的定义(带有请求的 url 参数)未被使用。

虽然,在上面描述的例子中,这似乎是一个功能的遗漏,但我越想,这个功能甚至没有完全意义。如果 parent 的 URL 与 child 完全不同怎么办:

.state("parent", {url: "/parent/{something}"})
.state("child",  {url: "^/child"})

$stateParams.something 应该等于什么?