微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AngularJS自定义指令详解有分页插件代码

前言

除了 AngularJS 内置的指令外,我们还可以创建自定义指令。

通过 .directive() 函数添加自定义的指令。

调用自定义指令时,需要在HTMl 元素上添加自定义指令名。

自定义指令命名规则:使用驼峰命名法来命名,即除第一个单词外的首字母需大写。如: myDirective。

在html页面调用该指令时需要以 - 分割,如: my-directive。示例代码

rush:xhtml;">

html页面调用自定义指令的四种方式

通过在自定义指令里添加 restrict 属性,根据设置不同的值来决定html页面调用方式,如:

rush:js;"> var app = angular.module("myApp",[]); app.directive("myDirective",function() { return { restrict : "A",//只能通过属性调用 template : "

自定义指令!

" }; });

restrict值的不同,决定了调用方式的不同

属性属性名

restrict 认值为 EA,即在html页面可通过元素名和属性名来调用自定义指令。

自定义指令属性详解

调用方式 示例
属性 调用方式,A、C、E、M页面代码写于此。只能与templateUrl二选其一URL地址加载模板。只能与template二选其一标签替换成temple中定义的内容,页面上不会再有标签;false :则append(追加)在当前元素上,即模板的内容包在标签内部。认false。内容转移到模板中cope默认值): 使用父作用域作为自己的作用域(每个引用自定义指令的标签若其中一个标签改变某一变量值,则会影响其他标签的值 )。true: 新建一个作用域,该作用域继承父作用域(两个引用自定义指令的标签间的变量互不影响)。JavaScript对象:与父作用域隔离,并指定可以从父作用域访问的变量函数包括添加监听器等修改DOM模板的副本,可以返回链接函数

对表格里的知识进行延伸

1.templateUrl

如果template里拼写的html页面代码十分的多页复杂,拼字符串的话就太麻烦啦,这里我们就可以选择templateUrl。我们可以将要拼写的html页面代码独立到一个页面里,如template.html;然后再指定该html文件所在的路径即可,如templateUrl:”template.html”。用到该自定义指令时,会自动一个http请求来获取template.html对应的模板内容。这样做的缺点是,多了一个http请求。别急,可以改进的:

angularjs规定了模板还可以用

上面代码写在html页面的ng-controller指令所在标签的里面,这样就不用再去请求它了。示例:

rush:xhtml;"> <Meta charset="utf-8">

有多个模板时,我们可以将所有的模板集中在一个文件中,只需加载一次,然后根据id的不同调用不同的模板。

2.transclude

定义是否将当前元素(html页面自定义指令)的内容转移到模板中。 模板中要接收当前元素内容标签需要使用ng-transclude指令。

rush:js;">
自定义指定令内容

<script type="text/ng-template" id="template.html">

模板内容
//模板接收上面自定义指令间的内容

3.什么是scope的父作用域

引用自定义指令的html页面的控制器所能控制的范围。下面代码的父作用域就是myController所控制的范围

rush:xhtml;">

4.scope属性的值是对象(object)时的用法

AngularJS内置指令的用法:ng-model=”obj”,通过obj这个变量双向绑定值,controller里变了,html页面也跟着变化。这说明,内置指令不仅可作为属性,还可动态改变值,这个要是不懂的,看看基础语法。如下代码

rush:xhtml;">
内容:

自定义指令当然也需要实现这种功能啦。scope属性为对象时,可为自定义指令指定一个可以绑定值的属性。这里还得说明一下的是,这个scope属性自定义指令里link属性里的scope参数是一个变量。

rush:xhtml;">

有了前面的一个示例,下面再来说说绑定策略:即用符号前缀给自定义指令传值。它是一个键值对,键是在自定义指令中使用的,值里符号后面的字符串是html页面自定义指令的属性名;如果值里只有符号,则html页面自定义指令的属性名就是键名。

符号 页面自定义指令里的val属性的值可传给link的scope使用。第一种写法——str : “@”,这种写法html页面的指令属性名为str属性名为val属性中,数据值可以是任意类型的。第一种写法:name : “=”,这种写法html页面自定义指令属性名就是name属性名是username一个函数,可以在指令中调用。第一种写法:getName:”&”,这种写法html页面自定义指令属性名就是gegName属性名是getUserName

其余两种符号用法

rush:xhtml;">
自定义指定令的内容555
rush:xhtml;">
test()">

5.controller属性

controller属性用于提供对外的接口,即该自定义指令会被其他自定义指令调用。所谓的接口,就是this后的变量或方法

controller可以使用的参数,作用域、节点、节点的属性、节点内容的迁移,这些都可以通过依赖注入被传进来,所以你可以根据需要只写要用的参数,有$scope,Z$element,$attrs,$transclude。

调用自定义指令的指令需要放在该指令之间。假定firstDirective指令是要被调用自定义指令,expander是调用者指令。如下:

rush:xml;">

既然firstDirective内部还有指令,则firstDirective必须配置transclude属性为true。代码如下:

rush:js;"> //用于被调用自定义指令 app.directive('firstDirective',function(){ return { template : '
',replace : true,transclude : true,controller :function(){ this.getData = function(val){ var data = 3 * val; return data; } this.a = "abc"; } } });

调用其他指令的自定义指令必须配置require属性指定指令名。然后在link函数里就可注入要调用的指令。

rush:js;"> //自定义指令 app.directive('expander',function(){ return { templateUrl : 'template.html',require : '^?firstDirective',//引用其他自定义指令,^表示从父节点开始找,?表示将告诉$compile服务,如果所需的指令没找到,不要抛出异常 scope : { title : '=attribute' },link : function(scope,element,attris,firstDirct){//注入 console.log(firstDirct.a)//调用其他指令的变量 console.log(firstDirct.getData(6)) //调用其他指令的方法 } }; });

6.link属性用法

link后的方法在指令中负责执行DOM 操作和注册事件监听器等。link函数有五个参数(scope,attrs,controller,linker)。link 方法的参数解释:

scope:

它与自定义指令里的scope属性一个东西。它是指令scope的引用,所以可改名为sco等其他名字。scope 变量在初始化时是不被定义的,link 方法注册监视器监视值变化事件。

element:

包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jquery,还可以使用Angular's jqLite )。

controller:

在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互,如前面的例子。

注意:当调用link 方法时, 通过值传递(”@”)的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法

7.link与compile的区别

compile函数有三个参数(cElement,cAttrs,cLinker),使用compile函数可以在ng创建原始dom实例以及创建scope实例之前,改变原始的dom(template element);可以应用于当需要生成多个element实例但只有一个template element的情况,ng-repeat就是一个最好的例子。它就在是compile函数阶段改变原始的dom生成多个原始dom节点,然后每个又生成element实例。因为compile只会运行一次,所以当你需要生成多个element实例的时候是可以提高性能的。

link函数有五个参数(scope,ctrl,linker)。

link又分为pre-link和post-link,在代码里直接用pre和post表示,当我们直接使用link时,认跟post一样。我在网上找了个例子来说明一下区别,代码如下:

rush:xhtml;">
Hello

注意打印结果:

Hello levelTwo: compile => Hello levelThree: compile => Hello levelOne: pre link => Hello

levelTwo: pre link =>

Hello

levelThree: pre link =>
Hello

levelThree: post link =>
Hello
levelTwo: post link =>

Hello

levelOne: post link =>

Hello

分析打印结果:

运行levelone指令中的compile函数,ng就会递归遍历它的dom节点,然后在level-two与level-three上面重复这些操作。所以会依次打印连续三个compile。

pre会在所有compile执行完后且在所有post之前执行。这样可以在执行post前执行一些其他代码,有些类似AOP。

由上面结果可知,post的执行顺序却是先levelthree最后levelone,即反向调用相关联的post-link函数。这么做的好处是,当我们运行levelone时,保证leveltwo与levelthree都已经执行过了,这样就会更安全。所以认的link就是post。

一个我做过的分页例子

之所以展示这个代码,主要是给一些朋友看看真实的项目,,多余的东西删掉了,具体的注入这里就不在讲了。

html页面代码

rush:xhtml;">

控制器代码

rush:js;"> "use strict";//严格

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){
//弹出框,没有查到数据
} else {
alert(result.i);
}
};

var getTableDataError = function(result) {
alert(result);
};
/重要的代码,这个paginationConf与自定义指令双向绑定数据/
$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);

}]);
});

自定义指令代码:也算是angularJS的分页插件

rush:js;"> /** * 分页插件封装s-pagination.js * @date 2016-05-06 * @author Peter */

angular.module('s.pagination',[]).directive('sPagination',[function(){//自定义指令
return {
restrict: 'E',//仅限元素名调用
template: '<div class="page-list">' +
'<ul class="pagination" ng-show="conf.totalItems > 0">' +
'<li ng-class="{disabled: conf.currentPage == 1}" ng-click="prevPage()">«' +
'<li ng-repeat="item in Pagelist track by $index" ng-class="{active: item == conf.currentPage,separate: item == \'...\'}" ' +
'ng-click="changeCurrentPage(item)">' +
'{{ item }}' +
'' +
'<li ng-class="{disabled: conf.currentPage == conf.numberOfPages}" ng-click="nextPage()">»' +
'' +
'<div class="page-total" ng-show="conf.totalItems > 0">' +
'第<input type="text" ng-model="jumpPageNum" ng-keyup="jumpToPage($event)"/>页 ' +
'每页<select ng-model="conf.itemsPerPage" ng-options="option for option in conf.perPageOptions ">' +
'/共

{{ conf.totalItems }}

条' +
'
' +
'<div class="no-items" ng-show="conf.totalItems <= 0">暂无数据' +
'',replace: true,scope: {
conf: '='//双向绑定数据
},link: function(scope,attrs){
// 变更当前页
scope.changeCurrentPage = function(item) {
if(item == '...'){
return;
}else{
scope.conf.currentPage = item;
}
};

// 定义分页的长度必须为奇数 (default:5)
scope.conf.pagesLength = parseInt(scope.conf.pagesLength) ? parseInt(scope.conf.pagesLength) : 5 ;
if(scope.conf.pagesLength % 2 === 0){
// 如果不是奇数的时候处理一下
scope.conf.pagesLength = scope.conf.pagesLength -1;
}

// conf.erPageOptions
if(!scope.conf.perPageOptions){
scope.conf.perPageOptions = [10,20,30,40,50];
}

// Pagelist数组
function getPagination(newValue,oldValue) {
//新增属性search 用于附加搜索条件改变时触发
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
s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems = parseInt(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems) ? parseInt(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems) : 0;

// conf.itemsPerPage (default:15)
s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage = parseInt(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage) ? parseInt(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage) : 15;

// numberOfPages
s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages = Math.ceil(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems/s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage);

// judge currentPage > s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.numberOfPages
if(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage < 1){
 scope.conf.currentPage = 1;
}

// 如果分页总数>0,并且当前页大于<a href="https://www.jb51.cc/tag/fenye/" target="_blank" class="keywords">分页</a>总数
if(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages > 0 && s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage > s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages){
 s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage = s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages;
}

// jumpPageNum
s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.jumpPageNum = s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage;

// 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
var perPageOptionsLength = s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.perPageOptions.length;
// 定义状态
var perPageOption<a href="https://www.jb51.cc/tag/sst/" target="_blank" class="keywords">sst</a>atus;
for(var i = 0; i < perPageOptionsLength; i++){
 if(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.perPageOptions[i] == s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage){
  perPageOption<a href="https://www.jb51.cc/tag/sst/" target="_blank" class="keywords">sst</a>atus = true;
 }
}
// 如果itemsPerPage在不在perPageOptions数组中,就把itemsPerPage加入这个数组中
if(!perPageOption<a href="https://www.jb51.cc/tag/sst/" target="_blank" class="keywords">sst</a>atus){
 s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.perPageOptions.push(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage);
}

// 对选项进行sort
s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.perPageOptions<a href="https://www.jb51.cc/tag/so/" target="_blank" class="keywords">.so</a>rt(function(a,b){return a-b});

s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a> = [];
if(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages <= s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.pagesLength){
 // 判断总页数如果小于等于<a href="https://www.jb51.cc/tag/fenye/" target="_blank" class="keywords">分页</a>的长度,若小于则直接<a href="https://www.jb51.cc/tag/xianshi/" target="_blank" class="keywords">显示</a>
 for(i =1; i <= s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages; i++){
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(i);
 }
}else{
 // 总页数大于<a href="https://www.jb51.cc/tag/fenye/" target="_blank" class="keywords">分页</a>长度(此时分为三种情况:1.左边没有...2.右边没有...3.左右都有...)
 // 计算中心偏移量
 var offset = (s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.pagesLength - 1)/2;
 if(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage <= offset){
  // 左边没有...
  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 > s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages - offset){
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(1);
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push('...');
  for(i = offset + 1; i >= 1; i--){
   s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages - i);
  }
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.numberOfPages);
 }else{
  // 最后一种情况,两边都有...
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(1);
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push('...');

  for(i = Math.ceil(offset/2) ; i >= 1; i--){
   s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage - i);
  }
  s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.<a href="https://www.jb51.cc/tag/Pagelist/" target="_blank" class="keywords">Pagelist</a>.push(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.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){
 //请求数据
 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;
}
};

// 跳转页
scope.jumpToPage = function(){
scope.jumpPageNum = scope.jumpPageNum.replace(/[^0-9]/g,'');
if(scope.jumpPageNum !== ''){
scope.conf.currentPage = scope.jumpPageNum;
}
};

scope.$watch(function() {

if(!s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems) {
 s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems = 0;
}
if(angular.isUndefined(s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.search)) {
 s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.search = false;
}

var newValue = [s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.totalItems,s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.currentPage,s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.itemsPerPage,s<a href="https://www.jb51.cc/tag/cop/" target="_blank" class="keywords">cop</a>e.conf.search];
return newValue;

},getPagination,true);
}
};
}]);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

原文地址:https://www.jb51.cc/js/38685.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


说明 示例