AngulaJS的指令是一种非常强大的特性,一个ng-repeat就能让我们非常方便的展示一个数据列表,指令相当于是一个组件,为我们将一些东西封装起来了,提供了复用的可能性。个人认为自定义指令还是比较复杂的,下面开始攻关。
一、三个重要参数
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>获取数据</title> </head> <body ng-controller="directiveCtrul"> <h1 get-data>{{data}}</h1> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = "你好啊!"; }) .directive("getData",function(){ return function(scope,element,attrs){ console.log(scope['data']) } }) </script> </body> </html>
用directive方法创建自定义指令,directive方法有两个参数,第一个参数表示指令名字,第二个参数是一个工厂函数,工厂函数返回一个工人函数,工人函数有三个参数,分别表示应用指令元素的作用域,应用指令的元素的包装对象,应用指令的元素的特性对象。
二、生成元素,减少依赖,计算表达式
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>生成元素,减少依赖,处理变化</title> </head> <body ng-controller="directiveCtrul"> <div list-products='products' list-property="cat"></div> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.products = [ {name:"苹果",cat:"水果",price:5.0,expiry:100000000}, {name:"香蕉",cat:"水果",price:6.0,expiry:9}, {name:"桃子",cat:"水果",price:7.0,expiry:7}, {name:"22",cat:"yy",price:5.0,expiry:5}, {name:"33",cat:"yy",price:9.0,expiry:6}, {name:"44",cat:"yy",price:4.0,expiry:2}, {name:"55",cat:"yy",price:8.0,expiry:4}, {name:"ww",cat:"tt",price:4.0,expiry:7}, {name:"qq",cat:"tt",price:3.0,expiry:9}, ]; }) .directive("listProducts",function(){ return function(scope,element,attrs){ var data = scope[attrs['listProducts']]; console.log(data.length) var property = attrs['listProperty']; var listElem = angular.element("<ul>"); for (var i = data.length - 1; i >=0; i--) { //(function(){ listElem.append(angular.element("<li>") .text(data[i][property])); //})() } element.append(listElem); } }) </script> </body> </html>
上面的例子中,更具list-products 属性值从作用域拿到指定数据,通过list-property属性获取要显示的属性,用这个属性减少了依赖,这样做没有将要显示的属性写死,增加了灵活性。还存在一个问题就是如果对要显示的属性应用了过滤器,那么上述指令将无法工作,解决方法是使用计算表达式。像这个样子
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>生成元素,减少依赖,处理变化</title> </head> <body ng-controller="directiveCtrul"> <div list-products='products' list-property="price | currency"></div> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.products = [ {name:"苹果",cat:"水果",price:5.0,expiry:100000000}, {name:"香蕉",cat:"水果",price:6.0,expiry:9}, {name:"桃子",cat:"水果",price:7.0,expiry:7}, {name:"22",cat:"yy",price:5.0,expiry:5}, {name:"33",cat:"yy",price:9.0,expiry:6}, {name:"44",cat:"yy",price:4.0,expiry:2}, {name:"55",cat:"yy",price:8.0,expiry:4}, {name:"ww",cat:"tt",price:4.0,expiry:7}, {name:"qq",cat:"tt",price:3.0,expiry:9}, ]; }) .directive("listProducts",function(){ return function(scope,element,attrs){ var data = scope[attrs['listProducts']]; console.log(data.length) var property = attrs['listProperty']; var listElem = angular.element("<ul>"); for (var i = data.length - 1; i >=0; i--) { //(function(){ listElem.append(angular.element("<li>") .text(scope.$eval(property,data[i]))); //})() } element.append(listElem); } }) </script> </body> </html>
三、响应数据变化
有时候我们的数据模型可能会发生变化,这个时候我们的指令中显示的数据也应该相应发生变化才对。
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>响应变化</title> </head> <body ng-controller="directiveCtrul"> <div dir> </div> <button ng-click="change()">改变</button> <script type="text/javascript" src="../node_modules/angular/angular.min.js"></script> <script type="text/javascript"> angular.module('myApp',[]) .controller('directiveCtrul',function($scope){ $scope.data = "原来的数据"; var isChange = false; $scope.change = function(){ if(!isChange){ $scope.data = '新数据'; isChange=!isChange; }else{ $scope.data = '原来的数据'; isChange=!isChange; } } }) .directive("dir",function(){ return function(scope,element,attrs){ var data = scope['data']; var h = angular.element('<h1>').text(data); element.append(h); scope.$watch('data',function(newvalue,oldvalue){ h.text(newvalue); }) } }) </script> </body> </html>
用一个$watch监控我们可能发生变化的数据就可以了。
四、关于jqLite
jqLite是迷你版的jQuery,更jquery差不多。下面给出其重要的方法以备参考,不做展开。
1、遍历DOM
方法 | 干嘛的 |
children() | 找儿子 |
eq(index) | 从一组元素中返回指定位置的元素 |
find(selector) | 从后代中找指定的选择器的元素 |
next() | 找弟弟 |
parent() | 找爸爸 |
2、修改元素
方法 | 干嘛的 |
addClass(name) | 将选择的元素加一个class |
attr(name,[value]) | 获取或设置特性值 |
css(name,[vlaue]) | 获取或设置一个css属性值 |
hasClass(name) | 判断有没有指定的class |
prop(name,[value]) | 获取或设置第一个元素的值 |
removeAttr(name) | 移除一个特性 |
removeClass(name) | 移除一个class |
text([value]) | 设置或获得元素的文本 |
toggleClass(name) | 切换class |
val([value]) | 设置或者获取value值 |
3、创建与移除元素
方法 | 干嘛的 |
angular.element(html) | 创建 |
after(ele) | 在后插入 |
append(ele) | 作为最后的子元素插入 |
clone() | 克隆 |
prepend(ele) | 作为第一个子元素插入 |
remove() | 移出 |
replacewidth(ele) | 替换 |
wrap(ele) | 包裹 |
4、事件相关
方法 | 干嘛的 |
on(event,handler) | 绑定事件 |
off(event,handler) | 移出事件 |
triggerHandler(event) | 触发事件 |
本文来了一个指令的开胃菜,接下来学习更加复杂的指令。