UI路由器 - 单个状态下的多个嵌套命名视图

时间:2016-01-19 11:17:08

标签: angularjs angular-ui-router

index.html
--navbar.html
--content.html
  --customer.html
    --netScore.html
    --useExp.html
      --useExpNest1.html
      --useExpNest2.html
  --internalPerformance.html
--leftNavPanel.html

我有这种视图结构,我想一次性加载它们所以我打算把它放在一个状态。我看到了这个answer,但它似乎只适用于简单/双嵌套视图(我有3个或更多嵌套视图)。如何将其置于单一状态,或者如果不可能有更好的方法?

修改

我已经提出了这个解决方案,并且它以某种方式工作。

.state('index', {
    url: '/',
    views: {
        '': {
            templateUrl: 'app/modules/bulletin/views/index.view.html',
            controller: 'indexController'
        },
        'navbar@index': {
            templateUrl: 'app/modules/bulletin/views/index/navbar.view.html',
            controller: 'navbarController'
        },
        'content@index': {
            templateUrl: 'app/modules/bulletin/views/index/content.view.html',
            controller: 'contentController'
        },
        'leftNavPanel@index': {
            templateUrl: 'app/modules/bulletin/views/index/leftNavPanel.view.html',
            controller: 'contentController'
        }
    }
})
.state('index.content', {
    views: {
        'customer@index': {
            templateUrl: 'app/modules/bulletin/views/index/content/customer.view.html'
        },
        'internalPerformance@index': {
            templateUrl: 'app/modules/bulletin/views/index/content/internalPerformance.view.html'
        }
    }
})
.state('index.content.customer', {
    views: {
        'netScore@index.content': {
            templateUrl: 'app/modules/bulletin/views/index/content/customer/netScore.view.html'
        },
        'useExp@index.content': {
            templateUrl: 'app/modules/bulletin/views/index/content/customer/useExp.view.html'
        }
    }
})
.state('index.content.customer.useExp', {
    views: {
        'useExpNest1@index.content.customer': {
            templateUrl: 'app/modules/bulletin/views/index/content/customer/useExp/useExpNest1.view.html'
        },
        'useExpNest2@index.content.customer': {
            templateUrl: 'app/modules/bulletin/views/index/content/customer/useExp/useExpNest2.view.html'
        }
    }
})

然后将此代码添加到indexController(大多数父控制器)

$state.go('index.content');
$state.go('index.content.customer');
$state.go('index.content.customer.useExp');

但是这个答案仍然是错误的,因为,假设 netScore.html 有一些子视图,我们会为它创建路径,然后转到该状态,但 netScore 并且 useExp 状态处于同一级别,因此如果我们使用

,则只会加载其中一个状态
$state.go('index.content');
$state.go('index.content.customer');
$state.go('index.content.customer.netScore');
$state.go('index.content.customer.useExp');

编辑2 这是我到目前为止所做的plunker。视图名称略有不同,但您会清楚地看到问题

2 个答案:

答案 0 :(得分:1)

您可以使用命名视图和abstract:true属性的组合来默认加载子视图

angular.module('sampleModule', [
  'ui.router'  
]);


angular.module('sampleModule')
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.when('','/');
    $stateProvider
        .state('main', {
            url: '',
      abstract: true,
      templateUrl: 'main.view.html'
        })
        .state('main.load', {
            url: '/',
            abstract: true,
            views:{
              'content':{
                templateUrl:'content.view.html',
              },
              'navbar':{
                templateUrl:'navbar.view.html',
              }
            }
        })
        .state('main.load.customer', {
            url: '',
            abstract: true,
            views:{
              'customerPerception':{
                templateUrl:'content-customerPerception.view.html'
              },
              'customerExperience':{
                templateUrl:'content-customerExperience.view.html'
              }
            }
        })
        .state('main.load.customer.netTrustScore', {
            url: '',
            abstract: true,
            views: {
                'netTrustScore': {
                    templateUrl: 'content-customerPerception-netTrustScore.view.html'
                },
                'useExperience': {
                    templateUrl: 'content-customerPerception-useExperience.view.html'
                },
                'trustStatements': {
                    templateUrl: 'content-customerPerception-trustStatements.view.html'
                }
            }
        })
    .state('main.load.customer.netTrustScore.somethingElse', {
            url: '',
            views: {
                'abc': {
                    templateUrl: 'content-customerExperience-customerComplaints.view.html'
                },
        '': {
          templateUrl: 'content-customerExperience-networkQualityIndex.view.html'
        }
            }
        })
    ;
}])

.controller('mainController', ['$scope', '$state', function($scope, $state) {

    console.log('mainController initialized!');


}]);
这是一个pnkr https://plnkr.co/edit/BBAeWjnGbTsbO1lMguU9?p=preview

答案 1 :(得分:0)

感谢FB中AngularJS小组的成员。问题是我将两个兄弟视图放在两个不同的状态。 UI路由器无法同时加载两个状态。所以解决方案是将所有相同级别的视图放在一个子状态中。

让我们假设我们有这种结构:

index.html
--navbar.html
--content.html
  --customer.html
    --netScore.html
      --netScoreNest1.html
      --netScoreNest2.html
    --useExp.html
      --useExpNest1.html
      --useExpNest2.html
  --internalPerformance.html
--leftNavPanel.html

正确的路由就像这样

.state('index', {
    url: '/',
    views: {
        '': {
            templateUrl: 'index.view.html',
            controller: 'mainController'
        },
        'navbar@main': {
            templateUrl: 'index/navbar.view.html'
        },
        'content@main': {
            templateUrl: 'index/content.view.html'
        },
        'leftNavPanel@main': {
            templateUrl: 'index/leftNavPanel.view.html'
        }
    }
})
.state('index.subLevel', {
    views: {
        'customer@index': {
            templateUrl: 'index/content/customer.view.html'
        },
        'internalPerformance@index': {
            templateUrl: 'index/content/internalPerformance.view.html'
        }
        // IF LEFTNAVPANEL OR NAVBAR HAVE SUB VIEWS, PUT IT HERE
    }
})
.state('index.subLevel.subLevel2', {
    views: {
        'netScore@index.subLevel': {
            templateUrl: 'index/content/customer/netScore.view.html'
        },
        'useExp@index.subLevel': {
            templateUrl: 'index/content/customer/useExp.view.html'
        }
        // IF INTERNALPERFORMANCE HAVE SUB VIEWS, PUT IT HERE
    }
})
.state('index.subLevel.subLevel2.subLevel3', {
    views: {
        'netScoreNest1@index.subLevel.subLevel2': {
            templateUrl: 'index/content/customer/netScore/netScoreNest1.view.html'
        },
        'netScoreNest2@index.subLevel.subLevel2': {
            templateUrl: 'index/content/customer/netScore/netScoreNest2.view.html'
        },
        'useExpNest1@index.subLevel.subLevel2': {
            templateUrl: 'index/content/customer/useExp/useExpNest1.view.html'
        },
        'useExpNest2@index.subLevel.subLevel2': {
            templateUrl: 'index/content/customer/useExp/useExpNest2.view.html'
        }
    }
})

然后在mainController中,加载最内部的子状态,这将自动加载其所有父级的视图(最多为父级状态'index')

$state.go('index.subLevel.subLevel2.subLevel3');

就是这样。此外还有一个plunker,以便更容易理解。 (视图和结构与此帖略有不同。太懒了编辑)