AngularJS通过指令实现tabs切换功能
2016-08-12 本文已影响1977人
MakingChoice
最近在和同学忙一个创业的项目,博客更新的不是很多,今天下午刚好下雨,就写一个通过指令嵌套实现tabs功能的指令模块,这也是我在一个项目中应用到的。<p>
jdfw.gif
首先先来说一下指令嵌套,指令嵌套顾名思义就是两个以上的指令嵌套在一起,比如下面这样:
<A-deirective>
<B-directive></B-directive>
<C-directive></C-directive>
</A-directive>
下面这个tabs功能的指令,刚好用到了这个,可以让代码更加简洁。</br>
<!DOCTYPE html>
<html lang="en" ng-app="docsTabsExample">
<head>
<meta charset="UTF-8">
<title></title>
<script></script>
<script src="lib/angular.min.js" type="text/javascript"></script>
<script src="lib/angular-route.js" type="text/javascript"></script>
<script src="lib/jquery-2.1.4.min.js"></script>
<script src="lib/bootstrap.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/bootstrap.css" type="text/css"/>
<style>
.active{
background: red;
}
</style>
</head>
<body ng-controller="appCon">
<my-tabs><!--最外层指令-->
<my-pane tittle="ONE"><!--内层指令-->
<h4>One</h4>
<p>angularangularangularangularangularangularangular</p>
</my-pane>
<my-pane tittle="TWO"><!--内层指令-->
<h4>Two</h4>
<p>angularangularangularangularangularangularangular</p>
</my-pane>
<my-pane tittle="THERE"><!--内层指令-->
<h4>There</h4>
<p>bootstrapbootstrapbootstrapbootstrapbootstrapbootstrap</p>
</my-pane>
<my-pane tittle="FIVE"><!--内层指令-->
<h4>five</h4>
<p>jqueryjqueryjqueryjqueryjqueryjqueryjquery</p>
</my-pane>
</my-tabs>
</body>
<script>
var app=angular.module("docsTabsExample",['template'])
.controller("appCon",["$scope",function($scope){
}])
.directive("myTabs", function () {
return{
restrict:"EA",
transclude: true,
scope:{},
templateUrl:"myTabs.html",
controller:["$scope", function ($scope) {//使用controller让最内层指令来继承外层指令,这样内层就可以通过scope的传导,来与外层指令进行数据之间的传递
var panes = $scope.scopes = [];//
$scope.select= function (pane) {//实现tabs功能
angular.forEach(panes, function (scope) { //遍历所有内存指令scope,统一隐藏内容。
scope.selected=false;
});
pane.selected=true;//通过ng-repeat只
};
this.addScope= function (scope) {//由内层指令来继承,把内层指令的scope,传到进外层指令进行控制
if(panes.length===0){
$scope.select(scope);
}
panes.push(scope);//把内层指令数组,传入外层指令scope数组。
}
}]
}
})
.directive("myPane", function () {
return{
restrict:'EA',
scope:{
tittle:'@'
},
transclude: true,
require:'^myTabs',//继承外层指令
templateUrl:"myPane.html",
link: function (scope, elemenet,attrs,myTabsController) {
myTabsController.addScope(scope);//把内层指令的scope存入到外层指令中,让外层遍历。
}
}
});
angular.module("template",[])
.run(["$templateCache", function ($templateCache) {
$templateCache.put("myTabs.html","<div class='table'>" +
"<ul class='nav nav-tabs'>" +
"<li ng-repeat='pane in scopes' ng-class='{active:pane.selected}'>" +
"<a href='#' ng-click='select(pane)'>{{pane.tittle}}<a/>" +
"</li>" +
"</ul>" +
"<div ng-transclude class='tab-content'></div>" +
"</div>")
}])
.run(["$templateCache", function ($templateCache) {
$templateCache.put("myPane.html","<div class='table-pane' ng-show='selected' ng-transclude>" +
"</div>")
}])
</script>
</html>
整个指令的的实现原理就是通过指令的继承,把内层指令的scope暴露到外层指令中,这样就可以在外层指令控制内层指令的显示。这里还有另外一个要说明的,为了让指令更加有层次,更加有逻辑性,使用了<code>ng-transclude</code>,让指令的template内容,反向插入到标有<code>ng-transclude</code>的内容中。