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

最好的方式来描述我的情况是用我创造的图像:

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

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

对于循环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的区域中

如何构造一个AngularJS应用程序来处理如此复杂的模板嵌套,同时又使它们彼此独立呢?


当前回答

Angular ui-router支持嵌套视图。我还没有用过,但看起来很有前途。

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

其他回答

因为你目前只能有一个ngView指令…我使用嵌套指令控件。这允许您设置模板并在其中继承(或隔离)作用域。除此之外,我使用ng-switch甚至只是ng-show来选择我要显示的控件,基于来自$routeParams的内容。

这里有一些伪代码示例,可以让您了解我所谈论的内容。使用嵌套的子导航。

这是应用程序的主页面

<!-- 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.
        }
    };
});

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

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

我的索引页使用ng-view。然后在我的子页面上,我需要有嵌套的框架。我使用ng-include。 演示显示了一个下拉列表。我把我的换成了一个链接。 在函数中,我将放入$scope。模板= $scope.templates[0];美元的范围。模板= $scope.templates[1];

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

更新:看看AngularUI的新项目来解决这个问题


对于子节,就像利用ng-include中的字符串一样简单:

<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>

或者你可以创建一个对象,以防你到处都有子页面的链接:

$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-controller

我也在纠结于Angular中的嵌套视图。

一旦我掌握了ui-router,我就知道我再也不会回到angular的默认路由功能了。

下面是一个使用多级视图嵌套的示例应用程序

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个子视图。

Angular ui-router支持嵌套视图。我还没有用过,但看起来很有前途。

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