将嵌套指令的内容转换到外部指令中



我想创建一个新的AngularJS指令(outer-directive),它包装一些内容(例如html或其他指令),并在左侧动态创建一个小导航。

我没有运行这个样本。content-section指令仅用于对左侧菜单中的content指令进行分组,不需要任何标记。仅当content指令处于活动状态时,它才应在outer-directive占位符中显示其传入的内容。

有人对如何使用AngularjS 1.5解决这个问题有想法或提示吗?

伪代码示例:

<outer-directive>
<content-section heading="Section 1">
<content heading="Content 1 in Section 1">
<!-- some HTML or other directives, etc -->
</content>
<content heading="Content 2 in Section 1">
<!-- some HTML or other directives, etc -->
</content>
</content-section>
<content-section heading="Section 2">
<content heading="Content 1 in Section 2">
<!-- some HTML or other directives, etc -->
</content>
</content-section>
</outer-directive>

指令模板:

<div class="row">
<div class="col-sm-3">
<!-- some kind of left side menu (want to use uib-accordion directive here) -->
<ul>
<li ng-repeat="contentSection in contentSections">
<h3>{{contentSection.heading}}</h3>
<ul>
<li ng-repeat="content in contentSection">
<a href ng-click="showContent(content.$id)">{{content.heading}}</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="col-sm-9">
<!-- show active content here with ng-if -->
<ng-transclude></ng-transclude>
</div>
</div>

指令伪代码:

angular.module('myApp')
.directive('outerDirective',
[
function() {
return {
restrict: 'E',
transclude: true,
replace: true,
templateUrl: 'outer-template.html',
controller: [
'$scope',
function($scope) {
$scope.contentSections = [];
this.addContentSection = function(contentSectionScope) {
var that = this;
$scope.contentSections.push(contentSectionScope);
contentSectionScope.$on('$destroy',
function(event) {
that.removeContentSection(contentSectionScope);
});
};
this.removeContentSection = function(contentSectionScope) {
var index = $scope.contentSections.indexOf(contentSectionScope);
if (index !== -1) {
$scope.contentSections.splice(index, 1);
}
};

// ...
}
]
}
}
])
.directive('contentSection',
[
function() {
return {
restrict: 'E',
require: '^outerDirective',
transclude: true,
replace: true,
//template: '',
scope: {
heading: '@'
},
controller: [
'$scope',
function($scope,) {
$scope.contents = [];
this.addContent = function (contentScope) {
var that = this;
$scope.contents.push(contentScope);
contentScope.$on('$destroy',
function (event) {
that.removeContent(contentScope);
});
};
this.removeContent = function (contentScope) {
var index = $scope.contents.indexOf(contentScope);
if (index !== -1) {
$scope.contents.splice(index, 1);
}
};
}
],
link: function (scope, element, attrs, outerCtrl) {
outerCtrl.addContentSection(scope);
}
}
}
])
.directive('content',
[
function () {
return {
restrict: 'E',
require: '^contentSection',
transclude: true,
template: '<div ng-transclude></div>',
scope: {
heading: '@'
},
controller: [
'$scope',
function ($scope) {

}
],
link: function (scope, element, attrs, contentSectionCtrl) {
contentSectionCtrl.addContent(scope);
}
}
}
]);;

Angular UI的"Tabs"指令解决了这个问题。

在你的情况下,你会这样做:

angular.module('myApp', ['ui.bootstrap']);

你的HTML应该是:

<body ng-app="myApp">
<uib-tabset template-url="custom-tabset-template.html">
<uib-tab heading="Section 1">
<!-- some HTML or other directives, etc -->
Section 1 Content
</uib-tab>
<uib-tab heading="Section 2">
<!-- some HTML or other directives, etc -->
Section 2 Content
</uib-tab>
<uib-tab heading="Section 3">
<!-- some HTML or other directives, etc -->
Section 3 Content
</uib-tab>
</uib-tabset>
</body>

定制的tabset-template.html将是:

<div class="row">
<!-- You can use uib-accordion directive here. In that case you would 
have to replace the heading attr on the tab with a nested 
uib-tab-heading element inside each tab -->
<ul class="col-sm-3" ng-transclude></ul>
<div class="col-sm-9 tab-content">
<div class="tab-pane"
ng-repeat="tab in tabset.tabs"
ng-class="{active: tabset.active === tab.index}"
uib-tab-content-transclude="tab">
</div>
</div>
</div>

这是一个正在工作的plunker。

享受吧。

最新更新