多个嵌套状态AngularJS ui-router

时间:2015-01-18 00:00:44

标签: angularjs angular-ui-router

原谅这是一个愚蠢的问题,但我是AngularJS的新手,对于我的生活,我无法弄清楚为什么这个嵌套视图设置没有按预期运行。

我有一个顶级<div>

<div class="grid" ui-view></div>

其中有一个模块填充其视图:

angular.module('planttheidea',[
    'ui.router',
    'planttheidea.header',
    'planttheidea.mainContent',
    'planttheidea.footer'
])
    .config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider){
        $stateProvider
            .state('base',{
                url:'',
                views:{
                    '':{
                        templateUrl:'app/layout.view.html',
                        controller:'LayoutCtrl'
                    }
                }
            });

        $urlRouterProvider.otherwise('/');
    }])
    .controller('LayoutCtrl',function LayoutCtrl($scope,$stateParams){
        var layout = this;
    }); 

然后我获得了该布局视图的内容:

<header ui-view="header" class="header menubar col-p-100" ng-controller="HeaderCtrl"></header>
<main ui-view="main-content" class="main-content grid col-p-100" ng-controller="MainContentCtrl"></main>
<footer ui-view="footer" class="footer col-p-100" ng-controller="FooterCtrl"></footer>

现在我的页眉和页脚都有自己的模块:

angular.module('planttheidea.header',[
    'planttheidea.header.menu'
])
    .config(['$stateProvider','$urlRouterProvider',function($stateProvider){
        $stateProvider
            .state('base.header',{
                url:'',
                views:{
                    'header@base':{
                        templateUrl:'app/components/header/header.view.html',
                        controller:'HeaderCtrl as layoutHeaderCtrl'
                    }
                }
            });
    }])
    .controller('HeaderCtrl',function HeaderCtrl($scope,$stateParams){
        var layoutHeaderCtrl = this;
    });

angular.module('planttheidea.footer',[])
    .config(['$stateProvider','$urlRouterProvider',function($stateProvider){
        $stateProvider
            .state('base.footer',{
                url:'',
                views:{
                    'footer@base':{
                        templateUrl:'app/components/footer/footer.view.html',
                        controller:'FooterCtrl as layoutFooterCtrl'
                    }
                }
            });
    }])
    .controller('FooterCtrl',function FooterCtrl($scope,$stateParams){
        var layoutFooterCtrl = this;
    });

你可以看到它们几乎相同。头模块工作正常(它甚至有自己的嵌套ui-view用于菜单,工作正常),但是页脚代码没有路由ui-view。更糟糕的是,如果我将页脚代码复制并粘贴到标题模块中(仅使用base.header状态),它可以按预期工作:

angular.module('planttheidea.header',[
    'planttheidea.header.menu'
])
    .config(['$stateProvider','$urlRouterProvider',function($stateProvider){
        $stateProvider
            .state('base.header',{
                url:'',
                views:{
                    'header@base':{
                        templateUrl:'app/components/header/header.view.html',
                        controller:'HeaderCtrl as layoutHeaderCtrl'
                    },
                    'footer@base':{
                        templateUrl:'app/components/footer/footer.view.html',
                        controller:'FooterCtrl as layoutFooterCtrl'
                    }
                }
            });
    }])
    .controller('HeaderCtrl',function HeaderCtrl($scope,$stateParams){
        var layoutHeaderCtrl = this;
    })
    .controller('FooterCtrl',function FooterCtrl($scope,$stateParams){
        var layoutFooterCtrl = this;
    });

我已经验证了代码是否正确加载(我在页脚的控制器中执行了console.log()只是为了确保它一直在运行),所以我认为它必须是隔离到两个模块。我是否需要在相同的状态下声明所有布局视图,或者有没有办法将它们分解为单独的模块,就像我在这里做的那样?我必须相信它的可能性,因为我使用嵌套的菜单模块,但是这是嵌套的,而页脚是并行的,所以我担心这可能是问题。

任何帮助都会受到最多的赞赏,但请记住我正在学习AngularJS,所以虽然工作代码很棒(显然),但为什么会更加精彩的解释。

1 个答案:

答案 0 :(得分:1)

所以这里有一些问题我会先纠正,看看是否能解决你的问题。

让我们假设你有一个这样的DOM布局:

<div ui-view>
    <div ui-view="view1"></div>
</div>

然后你的路线看起来像这样(即使你将其他模块注入主模块,它也会被分成不同的模块 - 你就是这样)

.config(['$stateProvider','$urlRouterProvider',function($stateProvider){
        $stateProvider
            .state('base',{
                url:'/',
                templateUrl:'template.html',
                controller:'Ctrl as ctrl'
            })
            .state('base.view1',{
                url:'/view1',
                views:{
                    'view1':{
                        templateUrl:'template.html',
                        controller:'Ctrl2 as ctrl2'
                    }
                }
            });
    }])

有些事情需要注意:

因为我的base状态直接进入没有值的ui视图,所以我没有一个带有空字符串的视图对象,我只是完全排除它。

我的base.view1也分配了一个网址,因为它是一个不同的状态。

因为我的ui-view="view1"位于我的base州的ui视图中,所以我不需要将视图声明为view1@base,因为我需要这样做

<div ui-view="main"></div>


.config(['$stateProvider','$urlRouterProvider',function($stateProvider){
        $stateProvider
            .state('base',{
                url:'/',
                views : {
                    'main' : {
                        templateUrl:'template.html',
                        controller:'Ctrl as ctrl'
                    }
                }

            })
            .state('base.view1',{
                url:'/view1',
                views : {
                    'main@base' : {
                        templateUrl:'template.html',
                        controller:'Ctrl as ctrl'
                    }
                }

            });
    }])

在此示例中,我希望base.view1“接管”,可以说是base所在的视图。

我真的不明白为什么你有一个页眉和页脚作为不同的状态。也许这是因为我没有你的项目的大局,但它似乎超出了常态。通常,您将页眉和页脚作为父状态的一部分包含在内,然后让主内容区域切换为不同的嵌套状态。

希望这是有道理的,让我知道我是否可以澄清更多。