如何基于角度UI-Router中的$ stateParams动态创建嵌套状态

时间:2015-05-23 10:29:15

标签: angularjs angular-ui-router

我想根据传递的状态参数创建子状态(嵌套状态)。

例如,我有一个动态状态参数 'pageId' 。如果$stateparams.pageId'page2',那么我希望为此创建两个嵌套状态。

我该怎么做?提前谢谢。

这是为此创建的plunkr

Plnkr

app.config(['$stateProvider', '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider){
        $stateProvider.state('page', {
            url: '/:pageId',
            templateUrl: function($stateParams){
              return $stateParams.pageId +".tpl.html";
            }
        });

        $urlRouterProvider.otherwise('/page1');
    }]);

2 个答案:

答案 0 :(得分:2)

a working plunker

我们可以创造两种状态。一个不会使用嵌套视图,第二个将使用嵌套视图。

// state without nested
.state('pageWithout', {
  url: '/{pageId:(?:page1|page3|page5)}',
  templateUrl: "page1.tpl.html",
})
// state with nested
.state('pageWith', {
  url: '/:pageId',
  views : {
    '' : {
      templateUrl: "page2.tpl.html",
    },
    '@pageWith' : {
      template: "<h2>the SECOND content for state with nested views</h2",
    }
  }
});

因此,诀窍是使用一些模式来说明哪个pageId值应该转到第一个状态。检查

UrlMatcher

负责 url : 'url def...' 处理

通过这种方式,我们将类似的链接转换为不同的状态,具有不同的嵌套视图结构:

// without nested views
<a href="#/page1">
<a href="#/page3">
<a href="#/page5">

// with nested views
<a href="#/page2">
<a href="#/pageA">
<a href="#/pageB">

检查it here

EXEND,带有子状态和一些默认值。 udpated plunker

因此,我们可以创建第二个州的少数孩子:

// children
.state('pageWith.defaultChild', {
  url: '/default',
  views : { 
    '' : {
      template: "<h3>the pageWith.defaultChild </h3",
    }
  }
}) 
.state('pageWith.childWithParams', {
  url: '/{id:int}',
  views : {
    '' : {
      template: "<h3>the child with ID param {{$stateParams.id}} </h3",
    }
  }
});

基于此解决方案:

Redirect a state to default substate with UI-Router in AngularJS

我们可以使用 redirectTo

来装饰我们的父状态
.state('pageWith', {
  url: '/:pageId',
  redirectTo: 'pageWith.defaultChild',
  ...

只需添加这个简单的监听器

.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params)
      }
    });
}]);

检查默认state redirect here

答案 1 :(得分:0)

我不清楚你明白你想要做什么,这是你想要做的吗?

app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider){
    $stateProvider
        .state('page', {
            url: '/:pageId',
            templateUrl: function($stateParams){
                return $stateParams.pageId +".tpl.html";
            },
        });
        .state('page.firstchild', {
            url: '/foo', // will have url /:pageId/foo because it inherits from its parent
        })
        .state('page.secondchild', {
            url: '/bar' // same here
        })

    $urlRouterProvider.otherwise('/page1');
}]);