ui-router— having a route's URL share the same

2019-07-25 00:05发布

I'd like to do something like this in my application, where the same level of the URL hits the either the baz state, that absolutely named, or the biz state that takes a parameter.

angular.module('foo')
.config(function($stateProvider){
  $stateProvider
  .state('baz', {
    url: '/baz',
    templateUrl: '/templates/baz.html'
  })
  .state('biz', {
    url: '/:biz',
    templateUrl: '/templates/biz.html',
    resolve: {
      biz: function($stateParams){
        // resolve whatever $stateParams.biz should be
      }
    }
  })
})

However, what's happening is ui-router is always hitting the biz state, and interpreting "baz" as a parameter for that state. Is there an elegant way to let ui-router know that anything that hits "/baz" should resolve to the baz state?

I know I can use $stateChangeStart and do something like this:

$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
  if (toParams.biz === "baz"){
    event.preventDefault();
    $state.go('baz')
  }
})

But this is far from elegant and seems like a hack.

1条回答
爷、活的狠高调
2楼-- · 2019-07-25 00:29

I created a plunker here, which in fact shows, that the above state snippet is WORKING. Why, because these states are defined in the correct order:

.state('baz', {
    url: '/baz', // url '/baz' is registered first, will be find and used
    ...
})
.state('biz', {
    url: '/:biz', // '/baz' will never reach this, because is already handled
    ...

The way how we can make it broken, is to switch the state def:

.state('biz', {
    url: '/:biz', // '/baz' will be handled by this state
    ...
.state('baz', {
    url: '/baz', // url '/baz' never reach this state def...
    ...
})

Check the broken link here

Summary:

state definition order is important. The first state url match is used

查看更多
登录 后发表回答