前言
除了 AngularJS 內(nèi)置的指令外,我們還可以創(chuàng)建自定義指令。
通過(guò) .directive() 函數(shù)來(lái)添加自定義的指令。
調(diào)用自定義指令時(shí),需要在HTMl 元素上添加自定義指令名。
自定義指令命名規(guī)則:使用駝峰命名法來(lái)命名,即除第一個(gè)單詞外的首字母需大寫(xiě)。如: myDirective。
在html頁(yè)面調(diào)用該指令時(shí)需要以 - 分割,如: my-directive。示例代碼:
<body ng-app="myApp">
<my-directive></my-directive>
<script>
var app = angular.module("myApp", []);
app.directive("myDirective", function() {
return {
template : "<h1>模板:可以寫(xiě)自己的html頁(yè)面代碼</h1>"
};
});
</script>
</body>
html頁(yè)面調(diào)用自定義指令的四種方式
通過(guò)在自定義指令里添加 restrict 屬性,根據(jù)設(shè)置不同的值來(lái)決定html頁(yè)面的調(diào)用方式,如:
var app = angular.module("myApp", []);
app.directive("myDirective", function() {
return {
restrict : "A",//只能通過(guò)屬性調(diào)用
template : "<h1>自定義指令!</h1>"
};
});
restrict值的不同,決定了調(diào)用方式的不同
| 屬性值 |
調(diào)用方式 |
示例 |
| A (Attribute首字母) |
屬性名 |
<div my-directive></div> |
| C (Class 首字母) |
類(lèi)名 |
<div class='my-directive'></div> |
| E (Element 首字母) |
元素名 |
<my-directive></my-directive> |
| M |
注釋 |
<!-- 指令: my-directive> |
restrict 默認(rèn)值為 EA, 即在html頁(yè)面可通過(guò)元素名和屬性名來(lái)調(diào)用自定義指令。
自定義指令屬性詳解
| 屬性 |
值類(lèi)型 |
說(shuō)明 |
| restrict |
string |
指令的調(diào)用方式,A、C、E、M |
| priority |
number |
指令執(zhí)行的優(yōu)先級(jí) |
| template |
string |
指令使用的模板,可將html頁(yè)面代碼寫(xiě)于此。只能與templateUrl二選其一 |
| templateUrl |
string |
從指定的url地址加載模板。只能與template二選其一 |
| replace |
boolean |
是否用模板替換當(dāng)前元素。true : 將指令標(biāo)簽替換成temple中定義的內(nèi)容,頁(yè)面上不會(huì)再有<my-directive>標(biāo)簽;false :則append(追加)在當(dāng)前元素上,即模板的內(nèi)容包在<my-directive>標(biāo)簽內(nèi)部。默認(rèn)false。 |
| transclude |
boolean |
是否將當(dāng)前元素的內(nèi)容轉(zhuǎn)移到模板中 |
| scope |
boolean /object |
指定指令的作用域。false(默認(rèn)值): 使用父作用域作為自己的作用域(每個(gè)引用自定義指令的標(biāo)簽若其中一個(gè)標(biāo)簽改變某一變量值,則會(huì)影響其他標(biāo)簽的值 )。true: 新建一個(gè)作用域,該作用域繼承父作用域(兩個(gè)引用自定義指令的標(biāo)簽之間的變量互不影響)。JavaScript對(duì)象:與父作用域隔離,并指定可以從父作用域訪(fǎng)問(wèn)的變量 |
| controller |
function |
定義與其他指令進(jìn)行交互的接口函數(shù) |
| require |
string |
指定需要依賴(lài)的其他指令 |
| link |
function |
以編程的方式操作DOM,包括添加監(jiān)聽(tīng)器等 |
| compile |
function |
編程的方式修改DOM模板的副本,可以返回鏈接函數(shù) |
對(duì)表格里的知識(shí)進(jìn)行延伸
1.templateUrl
如果template里拼寫(xiě)的html頁(yè)面代碼十分的多頁(yè)復(fù)雜,拼字符串的話(huà)就太麻煩啦,這里我們就可以選擇templateUrl。我們可以將要拼寫(xiě)的html頁(yè)面代碼獨(dú)立到一個(gè)頁(yè)面里,如template.html;然后再指定該html文件所在的路徑即可,如templateUrl:”template.html”。用到該自定義指令時(shí),會(huì)自動(dòng)發(fā)一個(gè)http請(qǐng)求來(lái)獲取template.html對(duì)應(yīng)的模板內(nèi)容。這樣做的缺點(diǎn)是,多了一個(gè)http請(qǐng)求。別急,可以改進(jìn)的:
angularJS規(guī)定了模板還可以用<Script>標(biāo)簽定義:
<script type="text/ng-template" id="template.html">
<div>自定義指令模板用Script標(biāo)簽定義的方式,須放在html頁(yè)面ng-controller指令所在標(biāo)簽的內(nèi)部</div>
</script>
上面代碼寫(xiě)在html頁(yè)面的ng-controller指令所在標(biāo)簽的里面,這樣就不用再去請(qǐng)求它了。示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps./libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body >
<div ng-app="myApp" ng-controller="myController">
<!-- 引用自定義指令 -->
<my-directive></my-directive>
<!-- 模板代碼:須放在myController所在標(biāo)簽內(nèi)部 -->
<script type="text/ng-template" id="template.html">
<div> 自定義指令模板的templateUrl形式</div>
</script>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) { });
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
restrict:'E',
templateUrl : "template.html"
};
});
</script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
有多個(gè)模板時(shí),我們可以將所有的模板集中在一個(gè)文件中,只需加載一次,然后根據(jù)id的不同調(diào)用不同的模板。
2.transclude
定義是否將當(dāng)前元素(html頁(yè)面的自定義指令)的內(nèi)容轉(zhuǎn)移到模板中。
模板中要接收當(dāng)前元素內(nèi)容的標(biāo)簽需要使用ng-transclude指令。
<body >
<div ng-app="myApp" ng-controller="myController">
<!-- 引用自定義指令 -->
<my-directive>自定義指定令內(nèi)容</my-directive>
<!-- 模板代碼 -->
<script type="text/ng-template" id="template.html">
<div> 模板內(nèi)容</div>
<div ng-transclude></div>//模板接收上面自定義指令間的內(nèi)容
</script>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) { });
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
templateUrl : "template.html",
transclude : true//轉(zhuǎn)移到模板中
};
});
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
3.什么是scope的父作用域
引用自定義指令的html頁(yè)面的控制器所能控制的范圍。下面代碼的父作用域就是myController所控制的范圍
<body >
<div ng-app="myApp" ng-controller="myController">
<my-directive></my-directive><!-- 引用自定義指令 -->
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope){ });
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
template : "<h1>自定義指令!</h1>"
};
});
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
4.scope屬性的值是對(duì)象(object)時(shí)的用法
AngularJS內(nèi)置指令的用法:ng-model=”obj”,通過(guò)obj這個(gè)變量雙向綁定值,controller里變了,html頁(yè)面也跟著變化。這說(shuō)明,內(nèi)置指令不僅可作為屬性,還可動(dòng)態(tài)改變值,這個(gè)要是不懂的,看看基礎(chǔ)語(yǔ)法。如下代碼:
<div ng-app="myApp" ng-controller="myController">
要?jiǎng)討B(tài)變化的內(nèi)容: <input ng-model="obj">
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.obj = "這個(gè)字符串值會(huì)同步到html里";
});
</script>
自定義指令當(dāng)然也需要實(shí)現(xiàn)這種功能啦。scope屬性為對(duì)象時(shí),可為自定義指令指定一個(gè)可以綁定值的屬性。這里還得說(shuō)明一下的是,這個(gè)scope屬性與自定義指令里link屬性里的scope參數(shù)是一個(gè)變量。
<!-- =符號(hào)的用法-->
<body >
<div ng-app="myApp" ng-controller="myController">
<!-- 引用自定義指令:obj變量與控制器里的objc變量雙向綁定了值 -->
<my-directive speak="obj"></my-directive>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) {
$scope.obj="父作用域";//父作用域給自定義指令屬性賦的值
});
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
template : "<p>模板內(nèi)容</p>",
scope:{
title:"=speak"http://定義一個(gè)speak屬性供html頁(yè)面的自定義指令用。如果寫(xiě)成title:"="格式,則自定義指令里的屬性名就是title。
},
link: function postLink(scope, iElement, iAttrs) {
console.log(scope.title)//這里打印的值與控制器里的值一樣
}
};
});
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
有了前面的一個(gè)示例,下面再來(lái)說(shuō)說(shuō)綁定策略:即用符號(hào)前綴給自定義指令傳值。它是一個(gè)鍵值對(duì),鍵是在自定義指令中使用的,值里符號(hào)后面的字符串是html頁(yè)面自定義指令的屬性名;如果值里只有符號(hào),則html頁(yè)面自定義指令的屬性名就是鍵名。
| 符號(hào) |
說(shuō)明 |
示例 |
| @ |
值傳遞,單向綁定。html頁(yè)面自定義指令里的val屬性的值可傳給link的scope使用。第一種寫(xiě)法——str : “@”,這種寫(xiě)法html頁(yè)面的指令屬性名為str |
str : “@val”,屬性名為val |
| = |
雙向綁定數(shù)據(jù)到指令的屬性中,數(shù)據(jù)值可以是任意類(lèi)型的。第一種寫(xiě)法:name : “=”,這種寫(xiě)法html頁(yè)面的自定義指令屬性名就是name |
name : “=username”,屬性名是username |
| & |
使用父作用域中的一個(gè)函數(shù),可以在指令中調(diào)用。第一種寫(xiě)法:getName:”&”,這種寫(xiě)法html頁(yè)面的自定義指令屬性名就是gegName |
getName : “&getUserName”,屬性名是getUserName |
其余兩種符號(hào)用法:
<!-- @符號(hào)的用法 -->
<body >
<div ng-app="myApp" ng-controller="myController">
<!-- 引用自定義指令 -->
<my-directive title="obj" str="abcd">自定義指定令的內(nèi)容555</my-directive>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) {
$scope.obj="父作用域";//父作用域給自定義指令屬性賦的值
});
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
template : "<p >模板內(nèi)容</p>",
scope:{
title:"=",
str:"@"
},
link: function postLink(scope, iElement, iAttrs) {
console.log(scope.str)
console.log(scope.title)
}
};
});
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
<!-- &符號(hào)的用法 -->
<body >
<div ng-app="myApp" ng-controller="myController">
<!-- 引用自定義指令 -->
<my-directive fun="test()"></my-directive>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) {
$scope.test = function(){
console.log('自定義指令會(huì)調(diào)用該法,所以這句話(huà)會(huì)打印到控制臺(tái)上')
}
});
//創(chuàng)建自定義指令
app.directive("myDirective", function() {
return {
template : "<p >模板內(nèi)容</p>",
scope:{
fun:"&"http://屬性名直接是fun
},
link: function postLink(scope, iElement, iAttrs) {
scope.fun();//調(diào)用父作用域的方法,好似不能傳參,未深究。
}
};
});
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
5.controller屬性
controller屬性用于提供對(duì)外的接口,即該自定義指令會(huì)被其他自定義指令調(diào)用。所謂的接口,就是this后的變量或方法。
controller可以使用的參數(shù),作用域、節(jié)點(diǎn)、節(jié)點(diǎn)的屬性、節(jié)點(diǎn)內(nèi)容的遷移,這些都可以通過(guò)依賴(lài)注入被傳進(jìn)來(lái),所以你可以根據(jù)需要只寫(xiě)要用的參數(shù),有$scope,Z$element, $attrs, $transclude。
調(diào)用該自定義指令的指令需要放在該指令之間。假定firstDirective指令是要被調(diào)用的自定義指令,expander是調(diào)用者指令。如下:
<first-directive>
<expander ng-repeat="item in list" attribute="list">{{item.title}}:{{item.text}}</expander>
</first-directive>
既然firstDirective內(nèi)部還有指令,則firstDirective必須配置transclude屬性為true。代碼如下:
//用于被調(diào)用的自定義指令
app.directive('firstDirective',function(){
return {
template : '<div ng-transclude></div>',
replace : true,
transclude : true,
controller :function(){
this.getData = function(val){
var data = 3 * val;
return data;
}
this.a = "abc";
}
}
});
調(diào)用其他指令的自定義指令必須配置require屬性指定指令名。然后在link函數(shù)里就可注入要調(diào)用的指令。
//自定義指令
app.directive('expander',function(){
return {
templateUrl : 'template.html',
replace : true,
transclude : true,
require : '^?firstDirective',//引用其他自定義指令,^表示從父節(jié)點(diǎn)開(kāi)始找,?表示將告訴$compile服務(wù),如果所需的指令沒(méi)找到,不要拋出異常
scope : {
title : '=attribute'
},
link : function(scope,element,attris,firstDirct){//注入
console.log(firstDirct.a)//調(diào)用其他指令的變量
console.log(firstDirct.getData(6)) //調(diào)用其他指令的方法
}
};
});
6.link屬性用法
link后的方法在指令中負(fù)責(zé)執(zhí)行DOM 操作和注冊(cè)事件監(jiān)聽(tīng)器等。link函數(shù)有五個(gè)參數(shù)(scope,element,attrs,controller,linker)。link 方法的參數(shù)解釋?zhuān)?
scope: 它與自定義指令里的scope屬性是一個(gè)東西。它是指令scope的引用,所以可改名為sco等其他名字。scope 變量在初始化時(shí)是不被定義的,link 方法會(huì)注冊(cè)監(jiān)視器監(jiān)視值變化事件。
element: 包含指令的DOM元素的引用, link 方法一般通過(guò)jQuery 操作實(shí)例(如果沒(méi)有加載jQuery,還可以使用Angular’s jqLite )。
controller: 在有嵌套指令的情況下使用。這個(gè)參數(shù)作用在于把子指令的引用提供給父指令,允許指令之間進(jìn)行交互,如前面的例子。
注意:當(dāng)調(diào)用link 方法時(shí), 通過(guò)值傳遞(”@”)的scope 變量將不會(huì)被初始化,它們將會(huì)在指令的生命周期中另一個(gè)時(shí)間點(diǎn)進(jìn)行初始化,如果你需要監(jiān)聽(tīng)這個(gè)事件,可以使用scope.$watch 方法。
7.link與compile的區(qū)別
compile函數(shù)有三個(gè)參數(shù)(cElement,cAttrs,cLinker),使用compile函數(shù)可以在ng創(chuàng)建原始dom實(shí)例以及創(chuàng)建scope實(shí)例之前,改變?cè)嫉膁om(template element);可以應(yīng)用于當(dāng)需要生成多個(gè)element實(shí)例但只有一個(gè)template element的情況,ng-repeat就是一個(gè)最好的例子。它就在是compile函數(shù)階段改變?cè)嫉膁om生成多個(gè)原始dom節(jié)點(diǎn),然后每個(gè)又生成element實(shí)例。因?yàn)閏ompile只會(huì)運(yùn)行一次,所以當(dāng)你需要生成多個(gè)element實(shí)例的時(shí)候是可以提高性能的。
link函數(shù)有五個(gè)參數(shù)(scope,element,attrs,ctrl,linker)。
link又分為pre-link和post-link,在代碼里直接用pre和post表示,當(dāng)我們直接使用link時(shí),默認(rèn)跟post一樣。我在網(wǎng)上找了個(gè)例子來(lái)說(shuō)明一下區(qū)別,代碼如下:
<body>
<div ng-app="myApp" ng-controller="myController">
<level-one>
<level-two>
<level-three> Hello </level-three>
</level-two>
</level-one>
</div>
<script>
//創(chuàng)建模塊
var app = angular.module('myApp', []);
//創(chuàng)建控制器
app.controller('myController', function($scope) {
});
//自定義指令
function createDirective(name){
return function(){
return {
restrict: 'E',
compile: function(tElem, tAttrs){
console.log(name + ': compile => ' + tElem.html());
return {
pre: function(scope, iElem, iAttrs){
console.log(name + ': pre link => ' + iElem.html());
},
post: function(scope, iElem, iAttrs){
console.log(name + ': post link => ' + iElem.html());
}
}
}
}
}
}
app.directive('levelOne', createDirective('levelOne'));
app.directive('levelTwo', createDirective('levelTwo'));
app.directive('levelThree', createDirective('levelThree'));
</script>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
注意打印結(jié)果:
levelOne: compile =>
<level-two>
<level-three>
Hello
</level-three>
</level-two>
levelTwo: compile =>
<level-three>
Hello
</level-three>
levelThree: compile =>
Hello
levelOne: pre link =>
<level-two>
<level-three>
Hello
</level-three>
</level-two>
levelTwo: pre link =>
<level-three>
Hello
</level-three>
levelThree: pre link =>
Hello
levelThree: post link =>
Hello
levelTwo: post link =>
<level-three>
Hello
</level-three>
levelOne: post link =>
<level-two>
<level-three>
Hello
</level-three>
</level-two>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
分析打印結(jié)果:
運(yùn)行l(wèi)evelone指令中的compile函數(shù),ng就會(huì)遞歸遍歷它的dom節(jié)點(diǎn),然后在level-two與level-three上面重復(fù)這些操作。所以會(huì)依次打印連續(xù)三個(gè)compile。
pre會(huì)在所有compile執(zhí)行完后且在所有post之前執(zhí)行。這樣可以在執(zhí)行post前執(zhí)行一些其他代碼,有些類(lèi)似AOP。
由上面結(jié)果可知,post的執(zhí)行順序卻是先levelthree最后levelone,即反向調(diào)用相關(guān)聯(lián)的post-link函數(shù)。這么做的好處是,當(dāng)我們運(yùn)行l(wèi)evelone時(shí),保證leveltwo與levelthree都已經(jīng)執(zhí)行過(guò)了,這樣就會(huì)更安全。所以默認(rèn)的link就是post。
一個(gè)我做過(guò)的分頁(yè)例子
之所以展示這個(gè)代碼,主要是給一些朋友看看真實(shí)的項(xiàng)目,,多余的東西刪掉了,具體的注入這里就不在講了。
html頁(yè)面代碼:
<div class="wp-20" ng-controller="AppStatisticController" ng-cloak>
<div class="panel-footer">
<s-pagination conf="paginationConf"></s-pagination>
</div>
</div>
控制器代碼:
"use strict";//嚴(yán)格
define(["application-configuration", "s-pagination", "tableDataService"], function (app) {
app.register.controller("AppStatisticController", ["$scope", "$rootScope", "$stateParams","$http", "tableDataService",
function($scope, $rootScope, $stateParams, $http, tableDataService) {
var getTableDataSuccess = function(result) {
if(result.c == 1) {
$scope.title = result.title;
$scope.lists = result.pageList;
$scope.total = result.data;
$scope.paginationConf.totalItems = result.total;
}else if(result.c == 2){
//彈出框,沒(méi)有查到數(shù)據(jù)
} else {
alert(result.i);
}
};
var getTableDataError = function(result) {
alert(result);
};
/*重要的代碼,這個(gè)paginationConf與自定義指令雙向綁定數(shù)據(jù)*/
$scope.paginationConf = {
currentPage: 1,
itemsPerPage: 10,
pagesLength: 9,
search: false,
onChange: function() {
var param = {
"pageNo": this.currentPage,
"pageSize": this.itemsPerPage,
"timeType": $scope.formData.timeType,
"adStyle":$scope.formData.adStyle,
};
param.appId = $stateParams.appId;
tableDataService.getTableData(
param,
"ims/appStat.do",
getTableDataSuccess,
getTableDataError
);
}
};
$scope.$watch("formData",function(newValue,oldValue, scope) {
if(newValue.keywords == oldValue.keywords) {
$scope.paginationConf.search = true;
}
}, true);
}]);
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
自定義指令代碼:也算是angularJS的分頁(yè)插件
/**
* 分頁(yè)插件封裝s-pagination.js
* @date 2016-05-06
* @author Peter
*/
angular.module('s.pagination', []).directive('sPagination',[function(){//自定義指令
return {
restrict: 'E',//僅限元素名調(diào)用
template: '<div class="page-list">' +
'<ul class="pagination" ng-show="conf.totalItems > 0">' +
'<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()"><span>«</span></li>' +
'<li ng-repeat="item in pageList track by $index" ng-class="{active: item == conf.currentPage, separate: item == \'...\'}" ' +
'ng-click="changeCurrentPage(item)">' +
'<span>{{ item }}</span>' +
'</li>' +
'<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()"><span>»</span></li>' +
'</ul>' +
'<div class="page-total" ng-show="conf.totalItems > 0">' +
'第<input type="text" ng-model="jumpPageNum" ng-keyup="jumpToPage($event)"/>頁(yè) ' +
'每頁(yè)<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions "></select>' +
'/共<strong>{{ conf.totalItems }}</strong>條' +
'</div>' +
'<div class="no-items" ng-show="conf.totalItems <= 0">暫無(wú)數(shù)據(jù)</div>' +
'</div>',
replace: true,
scope: {
conf: '='//雙向綁定數(shù)據(jù)
},
link: function(scope, element, attrs){
// 變更當(dāng)前頁(yè)
scope.changeCurrentPage = function(item) {
if(item == '...'){
return;
}else{
scope.conf.currentPage = item;
}
};
// 定義分頁(yè)的長(zhǎng)度必須為奇數(shù) (default:5)
scope.conf.pagesLength = parseInt(scope.conf.pagesLength) ? parseInt(scope.conf.pagesLength) : 5 ;
if(scope.conf.pagesLength % 2 === 0){
// 如果不是奇數(shù)的時(shí)候處理一下
scope.conf.pagesLength = scope.conf.pagesLength -1;
}
// conf.erPageOptions
if(!scope.conf.perPageOptions){
scope.conf.perPageOptions = [10, 20, 30, 40, 50];
}
// pageList數(shù)組
function getPagination(newValue, oldValue) {
//新增屬性search 用于附加搜索條件改變時(shí)觸發(fā)
if(newValue[1] != oldValue[1] || newValue[2] != oldValue[2]) {
scope.conf.search = true;
}
// conf.currentPage
scope.conf.currentPage = parseInt(scope.conf.currentPage) ? parseInt(scope.conf.currentPage) : 1;
// conf.totalItems
scope.conf.totalItems = parseInt(scope.conf.totalItems) ? parseInt(scope.conf.totalItems) : 0;
// conf.itemsPerPage (default:15)
scope.conf.itemsPerPage = parseInt(scope.conf.itemsPerPage) ? parseInt(scope.conf.itemsPerPage) : 15;
// numberOfPages
scope.conf.numberOfPages = Math.ceil(scope.conf.totalItems/scope.conf.itemsPerPage);
// judge currentPage > scope.numberOfPages
if(scope.conf.currentPage < 1){
scope.conf.currentPage = 1;
}
// 如果分頁(yè)總數(shù)>0,并且當(dāng)前頁(yè)大于分頁(yè)總數(shù)
if(scope.conf.numberOfPages > 0 && scope.conf.currentPage > scope.conf.numberOfPages){
scope.conf.currentPage = scope.conf.numberOfPages;
}
// jumpPageNum
scope.jumpPageNum = scope.conf.currentPage;
// 如果itemsPerPage在不在perPageOptions數(shù)組中,就把itemsPerPage加入這個(gè)數(shù)組中
var perPageOptionsLength = scope.conf.perPageOptions.length;
// 定義狀態(tài)
var perPageOptionsStatus;
for(var i = 0; i < perPageOptionsLength; i++){
if(scope.conf.perPageOptions[i] == scope.conf.itemsPerPage){
perPageOptionsStatus = true;
}
}
// 如果itemsPerPage在不在perPageOptions數(shù)組中,就把itemsPerPage加入這個(gè)數(shù)組中
if(!perPageOptionsStatus){
scope.conf.perPageOptions.push(scope.conf.itemsPerPage);
}
// 對(duì)選項(xiàng)進(jìn)行sort
scope.conf.perPageOptions.sort(function(a, b){return a-b});
scope.pageList = [];
if(scope.conf.numberOfPages <= scope.conf.pagesLength){
// 判斷總頁(yè)數(shù)如果小于等于分頁(yè)的長(zhǎng)度,若小于則直接顯示
for(i =1; i <= scope.conf.numberOfPages; i++){
scope.pageList.push(i);
}
}else{
// 總頁(yè)數(shù)大于分頁(yè)長(zhǎng)度(此時(shí)分為三種情況:1.左邊沒(méi)有...2.右邊沒(méi)有...3.左右都有...)
// 計(jì)算中心偏移量
var offset = (scope.conf.pagesLength - 1)/2;
if(scope.conf.currentPage <= offset){
// 左邊沒(méi)有...
for(i =1; i <= offset +1; i++){
scope.pageList.push(i);
}
scope.pageList.push('...');
scope.pageList.push(scope.conf.numberOfPages);
}else if(scope.conf.currentPage > scope.conf.numberOfPages - offset){
scope.pageList.push(1);
scope.pageList.push('...');
for(i = offset + 1; i >= 1; i--){
scope.pageList.push(scope.conf.numberOfPages - i);
}
scope.pageList.push(scope.conf.numberOfPages);
}else{
// 最后一種情況,兩邊都有...
scope.pageList.push(1);
scope.pageList.push('...');
for(i = Math.ceil(offset/2) ; i >= 1; i--){
scope.pageList.push(scope.conf.currentPage - i);
}
scope.pageList.push(scope.conf.currentPage);
for(i = 1; i <= offset/2; i++){
scope.pageList.push(scope.conf.currentPage + i);
}
scope.pageList.push('...');
scope.pageList.push(scope.conf.numberOfPages);
}
}
if(scope.conf.onChange){
//請(qǐng)求數(shù)據(jù)
if(scope.conf.search) {
scope.conf.onChange();
scope.conf.search = false;
}
}
scope.$parent.conf = scope.conf;
}
// prevPage
scope.prevPage = function(){
if(scope.conf.currentPage > 1){
scope.conf.currentPage -= 1;
}
};
// nextPage
scope.nextPage = function(){
if(scope.conf.currentPage < scope.conf.numberOfPages){
scope.conf.currentPage += 1;
}
};
// 跳轉(zhuǎn)頁(yè)
scope.jumpToPage = function(){
scope.jumpPageNum = scope.jumpPageNum.replace(/[^0-9]/g,'');
if(scope.jumpPageNum !== ''){
scope.conf.currentPage = scope.jumpPageNum;
}
};
scope.$watch(function() {
if(!scope.conf.totalItems) {
scope.conf.totalItems = 0;
}
if(angular.isUndefined(scope.conf.search)) {
scope.conf.search = false;
}
var newValue = [scope.conf.totalItems, scope.conf.currentPage, scope.conf.itemsPerPage, scope.conf.search];
return newValue;
}, getPagination, true);
}
};
}]);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
|