【问题标题】:Angular UI-Router: nested viewsAngular UI-Router:嵌套视图
【发布时间】:2017-02-27 16:00:27
【问题描述】:

我有两个带有页眉和页脚的 col 布局。页眉具有页面导航(GetStarted、Component)。在 2 列中,一列用于 sidenav,另一列用于主要内容。 当“GetStarted”导航处于活动状态时,sidenav 会填充相应的链接(概述、示例) 当“组件”导航处于活动状态时,sidenav 会填充相应的链接(复选框、警报)

点击“概览”链接区域会填充其数据

 <ul class="nav nav-tabs">
      <li role="presentation" class="active"><a href="#checkbox--default">Default</a></li>
      <li role="presentation"><a href="#checkbox--disabled">Disabled</a></li>
    </ul>

    <section class="content__main__tab__content col-xs-12 col-sm-12 col-md-12 col-lg-12">
      <form id="checkbox--default">
        <div class="input__checkbox--default" id="checkbox--default">
        <!-- <div class="form-group"> -->
          <fieldset>
            <legend>Default</legend>
                <label for="gi-checkbox">Checkbox Label
                <div class="checkbox-input-wrapper group__input-wrapper">
                  <input type="checkbox" class="checkbox" id="gi-checkbox">
                </div>
                </label>
          </fieldset>             
        <!-- </div> -->
      </div> 
      </form>
</section>

主要内容有 2 个用于复选框状态的导航选项卡(默认和禁用)。通过单击“默认”,必须显示其内容,禁用也是如此。我是 Angular 的新手,我有点让第一级嵌套视图工作。但是整个事情都无法正常工作。这是代码示例

index.html

    <body ng-app="mendouiApp" id="mendo__home" data-spy="scroll" data-target=".scrollspy">    
        <nav class="navbar navbar-fixed-top navbar-inverse">
          <div class="container">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" ui-sref="home"><img src="images/gi-logo.png" alt="logo"/></a>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
              <ul class="nav navbar-nav">
                <li class="active"><a ui-sref="home">Get Started</a></li>
                <li><a ui-sref="components">Components</a></li>
              </ul>
            </div><!-- /.nav-collapse -->
          </div><!-- /.container  -->
        </nav><!-- /.navbar -->

         <div class="wrapper" ui-view></div> <!--/.container-->   

component.html

    <div class="content__wrapper">
        <div class="row">
          <div class="content__secondary content__secondary--l scrollspy">
              <ul id="sidenav-fixed-l" class="nav hidden-xs hidden-sm affix-top" data-spy="affix">
                <li>
                    <h5>COMPONENTS</h5>
                </li>
                <li ng-repeat="item in componentsList">
                    <a ui-sref="{{item.link}}" ng-cloak>{{item.name}}</a> 
                </li>
              </ul>
          </div>
          <div ui-view></div>      
        </div> <!--/.row-->
      </div> <!--/.content-wraper-->  

app.js

(function(){
    var mendouiApp = angular.module('mendouiApp', ['ui.router', 'ui.router.stateHelper']);

    mendouiApp.constant('COMPONENTS_LIST', {
        name: 'sidenav',
        templateUrl: '../components/components.list.html',
        abstract: true,
        children: [{
            name: 'alerts',
            url: '/alerts',
            templateUrl: '../components/alerts/alerts.html'
        }]
    });

    mendouiApp.config(function($stateHelperProvider, $urlRouterProvider, $locationProvider, $urlMatcherFactoryProvider, COMPONENTS_LIST) {
        $urlMatcherFactoryProvider.strictMode(false);
        $urlRouterProvider.otherwise('/home');
        $locationProvider.hashPrefix('!');
        $stateHelperProvider
            .state('home', {
                url: '/home',
                templateUrl: '../gettingstarted.html',
                controller: 'getStartedController'
            })
            .state('layouts', {
                url: '/layouts',
                templateUrl: '../layouts.html'
            })
            .state('screenpatterns', {
                url: '/screenpatterns',
                templateUrl: '../screenpatterns.html'
            })
            .state('yogi', {
                url: '/yogi',
                templateUrl: '../yogi.html'
            })
            .state('components', {
                url: '/components', 
                templateUrl: '../components.html',
                controller: 'componentsController'
            })
            .state(COMPONENTS_LIST, {
                keepOriginalNames: true
            })
            .state('components.button', {
                url: '/button',
                templateUrl: '../components/button/button.html'
            })          .state('components.checkbox', {
                url: '/checkbox',
                templateUrl: '../components/checkbox/checkbox.html'
            })
            .state('components.forms', {
                url: '/forms',
                deepStateRedirect: true,
                sticky: true,
                views: {
                    '': { templateUrl: '..forms.html' },
                    'inline@components.forms': {
                        templateUrl: '../components/forms/form-inline/forminline.html'
                    },
                    'default@components.forms': {
                        templateUrl: '../components/forms/form-default/formdefault.html'
                    },
                    'multicolumn@components.forms': {
                        templateUrl: '../components/forms/form-multicolumn/formmulticolumn.html'
                    }
                }           
            });
            // use the HTML5 History API
            $locationProvider.html5Mode({
              enabled: true,
              requireBase: false
            });
    });

    mendouiApp.controller('componentsController', ['$scope', '$state', 'sideNavService', function($scope, $state, sideNavService, COMPONENTS_LIST){
        $scope.componentsList = sideNavService.components;
        $scope.componentsnav = COMPONENTS_LIST.children;
        $scope.go = function(tab) {
            $state.go(tab.name);
        }
    }]);
    mendouiApp.controller('getStartedController', ['$scope', '$state', 'sideNavService', 'fixedSideNavService', function($scope, $state, sideNavService, fixedSideNavService ){
        $scope.getstartedList = sideNavService.getstarted;
    }]);

    /*** This is for the external url reference ***/
    mendouiApp.run(function($rootScope, $state, $stateParams, $window, fixedSideNavService, copyToClipBoardService) {
        $rootScope.$on('$stateChangeStart',
            function(event, toState, toParams, fromState, fromParams, $state, $stateParams) {
                if (toState.external) {
                    event.preventDefault();
                    $window.open(toState.url, '_self');
                }
        });
        $rootScope.$on('$viewContentLoaded', function(event){
            fixedSideNavService.fixedsidenav();
            copyToClipBoardService.copytoclipboard();
        });

        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
        $state.transitionTo('home');
    });
    })();

service.js

angular.module('mendouiApp').service('sideNavService', function() {
  return {
    "getstarted" : [
        {
            "name" : "Overview",
            "link" : "home.overview"
        }
        {
            "name" : "Summary",
            "link" : "home.overview"
        }

    ],
    "components" : [
        {
            "name" : "Alerts",
            "link"  :"components.alert"
        },
        {
            "name" : "Button",
            "link"  :"components.button"
        },
        {
            "name" : "Button Groups",
            "link"  :"components.buttongroup"
        },
        {
            "name" : "Button Icons",
            "link"  :"components.buttonicons"
        },
        {
            "name" : "Checkbox",
            "link"  :"components.checkbox"
        },
        {
            "name" : "Datepicker",
            "link"  :"components.datepicker"
        },
        {
            "name" : "Forms",
            "link" : "components.forms"
        }

    ]
 };
});

【问题讨论】:

  • 问题是什么?请稍微清理一下,一团糟,真的很难帮助你。

标签: angularjs angular-ui-router


【解决方案1】:

你的问题有点乱,但玩了一段时间后我明白了我做了这个小提琴:http://jsfiddle.net/canastro/c4kt2myc/2/我希望它能像你期望的那样工作。

这里主要关注的是:

.state("root.components.button", {
    url: '/components/button',
    views: {
        'main@': {
            template: `
                <div>
                    <a ui-sref="root.components.button.default">default</a>
                    <a ui-sref="root.components.button.disabled">disabled</a>
                    <div ui-view="buttonsContent"></div>
                </div>
            `
        }
    }
})
.state("root.components.button.default", {
    url: '/components/button/default',
    views: {
        'buttonsContent@root.components.button': {
            template: 'root.components.button.default'
        }
    }
})
.state("root.components.button.disabled", {
    url: '/components/button/disabled',
    views: {
        'buttonsContent@root.components.button': {
            template: 'root.components.button.disabled'
        }
    }
})

在第一层你有一个抽象的路线,所以你总是可以有你的基本布局。

然后在 Started / Components 路由中,将内容加载到 mainside ui-views。

在所有 Started 和 Component 子路由中,您只需覆盖 main 视图。

最后,在最后一个关卡中,您需要说您想要填充在先前状态中创建的 ui-view 的内容,方法是执行类似VIEWNAME@STATENAME 之类的操作。

【讨论】:

  • 感谢您花时间帮助我。我发布的上面的代码也有点这样做。但是我卡住的地方是在填充主和侧面 ui 视图时,现在用户将点击来自 sidenav 的链接。例如“说复选框”。现在主 ui-view 填充了它的内容。此内容具有导航选项卡,例如(堆叠,禁用,..)默认情况下,第一个选项卡内容应显示在选项卡下方的视图中。单击禁用时,uiview 将更改其内容。附上屏幕pdf
  • 更新了答案,我认为它可能符合您现在的需要