ui-router默认子状态不起作用

时间:2021-09-29 10:50:39

I'm testing UI-Router nested state, but I'm not able to set default state in parent/child scenario, please help.

我正在测试UI-Router嵌套状态,但是我无法在父/子场景中设置默认状态,请帮忙。

libraries:

  • angular 1.3.15
  • ui router: 0.2.15
  • ui路由器:0.2.15

navigation path:

/ - home
/settings - parent state/page
/settings.default - child 1
/settings.mail - child 2
/settings.phone - child 3

expected behavior:

when navigating to /settings, the default child 'general' state/page should be triggered/loaded

导航到/ settings时,应触发/加载默认的子“常规”状态/页面

actual behavior:

If I set 'settings' state 'abstrat: true', there will be error:

如果我将'settings'状态设置为'abstrat:true',则会出现错误:

Error: Cannot transition to abstract state 'settings'
    at Object.transitionTo (angular-ui-router.js:3143)
    at Object.go (angular-ui-router.js:3068)
    at angular-ui-router.js:4181
    at angular.js:16299
    at completeOutstandingRequest (angular.js:4924)
    at angular.js:5312

If I remove 'abstrat: true', there's no error, but when i navigate to /settings, default child state/page - general state not triggered, settings.html displayed but not loaded

如果我删除'abstrat:true',则没有错误,但是当我导航到/ settings时,默认子状态/页面 - 一般状态未触发,settings.html显示但未加载

app.js:

angular.module('test',['ui.router','sails.io'])     //config routing
.config(['$stateProvider','$urlRouterProvider','$locationProvider',
        function($stateProvider,$urlRouterProvider,$locationProvider) {

  $urlRouterProvider.otherwise('/');    
  $locationProvider.html5Mode(true);

  $stateProvider
    .state('home', {
        url: '/',
        templateUrl: 'views/index.html',
        controller: 'IndexController'
    })
    .state('settings', {
        abstract: true,
        url: '/settings',
        templateUrl: 'views/settings.html',
        controller: 'SettingsController'
    })
    .state('settings.general', {
        url: '',
        templateUrl: 'views/settings/general.html',
        controller: 'SettingsController'
    })
    .state('settings.mail', {
        url: '/mail',
        templateUrl: 'views/settings/mail.html',
        controller: 'SettingsController'
    })
    .state('settings.phone', {
        url: '/phone',
        templateUrl: 'views/settings/phone.html',
        controller: 'SettingsController'
    });
}]);

views/settings.html

<div class="container">
  <div class="row">
    <div class="col-md-3">
      <ul class="list-group">
        <li class="list-group-item"><a ui-sref=".general">General</a></li>
        <li class="list-group-item"><a ui-sref=".phone">Phone</a></li>
        <li class="list-group-item"><a ui-sref=".mail">Mail</a></li>
      </ul>
    </div>
    <div class="col-md-9">
      <div ui-view></div>
    </div>
  </div>
</div>

2 个解决方案

#1


10  

There is a working plunker

有一个工作的plunker

This would work, but just with url navigation, i.e. href:

这可行,但只是使用网址导航,即href:

  <a href="/settings"> // will work

But this will not - we cannot go to abstract state:

但这不会 - 我们不能去抽象状态:

  <a ui-sref="settings">settings</a>

But based on this Q & A:

但基于此问答:

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

We can remove abstract and create default state handling like this. There is updated plunker

我们可以删除抽象并创建这样的默认状态处理。有更新的plunker

// redirection engine
app.run(['$rootScope', '$state', function($rootScope, $state) {

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

The parent stat adjustment:

父级统计调整:

.state('settings', {
    //abstract: true,
    redirectTo: 'settings.general',
    url: '/settings',
    ...

Check it here

在这里查看

#2


1  

I realize this is an older question, but I thought I'd add something in case it helps someone else:

我意识到这是一个较老的问题,但我想我会添加一些东西,以防它帮助其他人:

Although you may not want to add a plugin to solve this problem, you should check out UI-Router-Extras

虽然您可能不想添加插件来解决此问题,但您应该查看UI-Router-Extras

There is a feature included there called "Deept State Redirect". This allows any state to save the most recently activated substate so that when you transition away, then back, the same substate (child state) will be active.

这里有一个名为“Deept State Redirect”的功能。这允许任何状态保存最近激活的子状态,以便当您转换,然后返回时,相同的子状态(子状态)将处于活动状态。

The part that would help your problem is being able to define a default child state. You do that by adding the "dsr" parameter and setting the "default" to whatever your child state is.

可以帮助您解决问题的部分是能够定义默认子状态。您可以通过添加“dsr”参数并将“default”设置为您的子状态。

function myRouterConfig ($stateProvider, $urlRouterProvider) {
 $stateProvider
    .state('parentState', {
        //Not in this file          
        parent: 'index', 
        sticky: true,
        //ui-router-extras deepStateRedirect option
        dsr: {  
            default: 'parentState.defaultChild'
        },
        url: '/parentState',
        views: {
            'main@index': {
                template: '<my-parentStateComponent>'
            }
        }           
    })
    .state('parentState.defaultChild', {
        url: '/defaultChild',
        views: {
            'child@parentState': {
                template: '<my-defaultChildComponent>'
            }
        }
    });

}

#1


10  

There is a working plunker

有一个工作的plunker

This would work, but just with url navigation, i.e. href:

这可行,但只是使用网址导航,即href:

  <a href="/settings"> // will work

But this will not - we cannot go to abstract state:

但这不会 - 我们不能去抽象状态:

  <a ui-sref="settings">settings</a>

But based on this Q & A:

但基于此问答:

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

We can remove abstract and create default state handling like this. There is updated plunker

我们可以删除抽象并创建这样的默认状态处理。有更新的plunker

// redirection engine
app.run(['$rootScope', '$state', function($rootScope, $state) {

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

The parent stat adjustment:

父级统计调整:

.state('settings', {
    //abstract: true,
    redirectTo: 'settings.general',
    url: '/settings',
    ...

Check it here

在这里查看

#2


1  

I realize this is an older question, but I thought I'd add something in case it helps someone else:

我意识到这是一个较老的问题,但我想我会添加一些东西,以防它帮助其他人:

Although you may not want to add a plugin to solve this problem, you should check out UI-Router-Extras

虽然您可能不想添加插件来解决此问题,但您应该查看UI-Router-Extras

There is a feature included there called "Deept State Redirect". This allows any state to save the most recently activated substate so that when you transition away, then back, the same substate (child state) will be active.

这里有一个名为“Deept State Redirect”的功能。这允许任何状态保存最近激活的子状态,以便当您转换,然后返回时,相同的子状态(子状态)将处于活动状态。

The part that would help your problem is being able to define a default child state. You do that by adding the "dsr" parameter and setting the "default" to whatever your child state is.

可以帮助您解决问题的部分是能够定义默认子状态。您可以通过添加“dsr”参数并将“default”设置为您的子状态。

function myRouterConfig ($stateProvider, $urlRouterProvider) {
 $stateProvider
    .state('parentState', {
        //Not in this file          
        parent: 'index', 
        sticky: true,
        //ui-router-extras deepStateRedirect option
        dsr: {  
            default: 'parentState.defaultChild'
        },
        url: '/parentState',
        views: {
            'main@index': {
                template: '<my-parentStateComponent>'
            }
        }           
    })
    .state('parentState.defaultChild', {
        url: '/defaultChild',
        views: {
            'child@parentState': {
                template: '<my-defaultChildComponent>'
            }
        }
    });

}