我的问题涉及如何在AngularJS应用程序中处理模板(也称为 partials )的复杂嵌套。
描述我的情况的最好方法是使用我创建的图像:
正如您所看到的,这可能是一个包含大量嵌套模型的相当复杂的应用程序。
该应用程序是单页面的,因此它会加载 index.html ,其中包含DOM中具有ng-view
属性的div元素。
对于圈子1 ,您会看到有一个主要导航会将相应的模板加载到ng-view
中。我是通过将$routeParams
传递给主app模块来实现的。这是我的应用程序中的一个示例:
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应用程序来处理模板的复杂嵌套,同时保持模板彼此分离?
答案 0 :(得分:197)
对于小节,它就像在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放在每个部分
的最顶层答案 1 :(得分:169)
好吧,因为你现在只能有一个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.
}
};
});
答案 2 :(得分:26)
您也可以出于同样的目的签出此库:
http://angular-route-segment.com
它看起来像你在寻找,它比ui-router更简单。来自demo site:
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>
答案 3 :(得分:17)
我也在使用Angular中的嵌套视图。
一旦我抓住ui-router,我知道我永远不会回到角度默认路由功能。
以下是使用多层视图嵌套
的示例应用程序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个子视图。
答案 4 :(得分:4)
您可以使用ng-include来避免使用嵌套的ng视图。
http://docs.angularjs.org/api/ng/directive/ngInclude
http://plnkr.co/edit/ngdoc:example-example39@snapshot?p=preview
我的索引页面我使用ng-view。然后在我需要嵌套框架的子页面上。我用ng-include。 该演示显示了一个下拉列表。我用链接点击替换了我的。 在函数中我会放$ scope.template = $ scope.templates [0];或$ scope.template = $ scope.templates [1];
$scope.clickToSomePage= function(){
$scope.template = $scope.templates[0];
};
答案 5 :(得分:2)
Angular ui-router支持嵌套视图。我还没有使用它,但看起来很有希望。