部分和模板的复杂嵌套

我的问题涉及如何在AngularJS应用程序中处理复杂的模板嵌套(也称为partials )。

描述我的情况的最好方法是用我创build的图像:

AngularJS页面图

正如你所看到的,这有可能是一个相当复杂的应用程序与大量的嵌套模型。

该应用程序是单页面的,所以它加载了一个index.html ,在DOM中包含一个div元素,并带有ng-view属性。

对于圆1 ,您会看到有一个Primary导航可以将相应的模板加载到ng-view 。 我通过传递$routeParams到主应用程序模块来做到这一点。 这里是我的应用程序中的一个例子:

 angular.module('myApp', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when("/job/:jobId/zones/:zoneId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/zone_edit.html' }). when("/job/:jobId/initial_inspection", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/initial_inspection.html' }). when("/job/:jobId/zones/:zoneId/rooms/:roomId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/room_edit.html' }) }]); 

在循环2中 ,加载到ng-view的模板有一个额外的子导航 。 这个子导航然后需要加载模板到它下面的区域 – 但由于ng-view已被使用,我不知道如何去做这个。

我知道我可以在第一个模板中包含额外的模板,但是这些模板将会非常复杂。 我想保留所有的模板分开,以使应用程序更容易更新,而不是必须加载为了访问其子的父模板的依赖。

在第3圈 ,你可以看到事情变得更加复杂。 子导航模板可能会有第二个子导航 ,需要将自己的模板加载到圆圈4的区域

如何构build一个AngularJS应用程序来处理如此复杂的模板嵌套,同时保持它们之间的相互独立?

那么,因为你目前只能有一个ngView指令…我使用嵌套的指令控制。 这允许您设置模板并在其中inheritance(或隔离)范围。 除此之外,我使用了ng-switch,甚至只是使用ng-show来根据$ routeParams中的内容来select显示的控件。

编辑这里有一些示例伪代码,让你知道我在说什么。 使用嵌套子导航。

这是主要的应用程序页面

 <!-- primary nav --> <a href="#/page/1">Page 1</a> <a href="#/page/2">Page 2</a> <a href="#/page/3">Page 3</a> <!-- display the view --> <div ng-view> </div> 

子导航的指令

 app.directive('mySubNav', function(){ return { restrict: 'E', scope: { current: '=current' }, templateUrl: 'mySubNav.html', controller: function($scope) { } }; }); 

子导航模板

 <a href="#/page/1/sub/1">Sub Item 1</a> <a href="#/page/1/sub/2">Sub Item 2</a> <a href="#/page/1/sub/3">Sub Item 3</a> 

主页面的模板(来自主导航)

 <my-sub-nav current="sub"></my-sub-nav> <ng-switch on="sub"> <div ng-switch-when="1"> <my-sub-area1></my-sub-area> </div> <div ng-switch-when="2"> <my-sub-area2></my-sub-area> </div> <div ng-switch-when="3"> <my-sub-area3></my-sub-area> </div> </ng-switch> 

主页面的控制器。 (从主导航)

 app.controller('page1Ctrl', function($scope, $routeParams) { $scope.sub = $routeParams.sub; }); 

子区域指令

 app.directive('mySubArea1', function(){ return { restrict: 'E', templateUrl: 'mySubArea1.html', controller: function($scope) { //controller for your sub area. } }; }); 

更新: 检查出AngularUI的新项目来解决这个问题


对于小节来说,就像利用ng-include中的string一样简单:

 <ul id="subNav"> <li><a ng-click="subPage='section1/subpage1.htm'">Sub Page 1</a></li> <li><a ng-click="subPage='section1/subpage2.htm'">Sub Page 2</a></li> <li><a ng-click="subPage='section1/subpage3.htm'">Sub Page 3</a></li> </ul> <ng-include src="subPage"></ng-include> 

或者你可以创build一个对象,以防万一你有链接到整个地方的子页面:

 $scope.pages = { page1: 'section1/subpage1.htm', ... }; 
 <ul id="subNav"> <li><a ng-click="subPage='page1'">Sub Page 1</a></li> <li><a ng-click="subPage='page2'">Sub Page 2</a></li> <li><a ng-click="subPage='page3'">Sub Page 3</a></li> </ul> <ng-include src="pages[subPage]"></ng-include> 

或者你甚至可以使用$routeParams

 $routeProvider.when('/home', ...); $routeProvider.when('/home/:tab', ...); $scope.params = $routeParams; 
 <ul id="subNav"> <li><a href="#/home/tab1">Sub Page 1</a></li> <li><a href="#/home/tab2">Sub Page 2</a></li> <li><a href="#/home/tab3">Sub Page 3</a></li> </ul> <ng-include src=" '/home/' + tab + '.html' "></ng-include> 

你也可以把ng控制器放在每个部分的最顶层

您也可以为同样的目的检出这个库:

http://angular-route-segment.com

它看起来像你在找什么,比使用路由器要简单得多。 从演示网站 :

JS:

 $routeSegmentProvider. when('/section1', 's1.home'). when('/section1/:id', 's1.itemInfo.overview'). when('/section2', 's2'). segment('s1', { templateUrl: 'templates/section1.html', controller: MainCtrl}). within(). segment('home', { templateUrl: 'templates/section1/home.html'}). segment('itemInfo', { templateUrl: 'templates/section1/item.html', controller: Section1ItemCtrl, dependencies: ['id']}). within(). segment('overview', { templateUrl: 'templates/section1/item/overview.html'}). 

顶级HTML:

 <ul> <li ng-class="{active: $routeSegment.startsWith('s1')}"> <a href="/section1">Section 1</a> </li> <li ng-class="{active: $routeSegment.startsWith('s2')}"> <a href="/section2">Section 2</a> </li> </ul> <div id="contents" app-view-segment="0"></div> 

嵌套的HTML:

 <h4>Section 1</h4> Section 1 contents. <div app-view-segment="1"></div> 

我也在Angular的嵌套视图中挣扎。

一旦我有了一个UI路由器我知道我永远不会回到angular度默认路由function。

这是一个使用多层视图嵌套的示例应用程序

 app.config(function ($stateProvider, $urlRouterProvider,$httpProvider) { // navigate to view1 view by default $urlRouterProvider.otherwise("/view1"); $stateProvider .state('view1', { url: '/view1', templateUrl: 'partials/view1.html', controller: 'view1.MainController' }) .state('view1.nestedViews', { url: '/view1', views: { 'childView1': { templateUrl: 'partials/view1.childView1.html' , controller: 'childView1Ctrl'}, 'childView2': { templateUrl: 'partials/view1.childView2.html', controller: 'childView2Ctrl' }, 'childView3': { templateUrl: 'partials/view1.childView3.html', controller: 'childView3Ctrl' } } }) .state('view2', { url: '/view2', }) .state('view3', { url: '/view3', }) .state('view4', { url: '/view4', }); }); 

可以看出有4个主视图(view1,view2,view3,view4)和view1有3个子视图。

你可以使用ng-include来避免使用嵌套的ng-views。

http://docs.angularjs.org/api/ng/directive/ngInclude
http://plnkr.co/edit/ngdoc:example-example39@snapshot?p=preview

我的索引页面我使用ng-view。 然后在我需要有嵌套帧的我的子页面。 我使用ng-include。 演示显示下拉菜单。 我用链接点击replace了我的。 在函数中我会把$ scope.template = $ scope.templates [0]; 或$ scope.template = $ scope.templates [1];

 $scope.clickToSomePage= function(){ $scope.template = $scope.templates[0]; }; 

Angular UI路由器支持嵌套视图。 我还没有使用它,但看起来非常有前途。

http://angular-ui.github.io/ui-router/