搞定angular1.x——自定义指令

        调用Module.directive方法,传入指令名称和工厂函数,返回一个对象。

        指令名称中每个大写字母会被认为是属性名中的一个独立的词,而每个词之间是以一个连字符分隔的。


  
  
  1. var myApp = angular.module('myApp', [])
  2.     .directive("unorderedList", function () {
  3.         return function(scope, element, attrs) {
  4.     
  5.         };
  6.     });

返回链式函数


  
  
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>AngularJS Demo</title>
  6.     <link rel="stylesheet" href="../css/bootstrap.css" />
  7.     <link rel="stylesheet" href="../css/bootstrap-theme.css">
  8.     <script src="../js/angular.js"></script>
  9. </head>
  10. <body ng-app="myApp" ng-controller="myCtrl">
  11.  
  12.     <div class="panel panel-default">
  13.         <div class="panel-heading">
  14.             <h3>Products</h3>
  15.         </div>
  16.         <div class="panel-body">
  17.             <div unordered-list="products"></div>
  18.         </div>
  19.     </div>
  20.  
  21.  
  22. </body>
  23. <script>
  24. var myApp = angular.module('myApp', [])
  25.     .controller('myCtrl', ["$scope", function ($scope) {
  26.         $scope.products = [
  27.             { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },
  28.             { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },
  29.             { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 }
  30.         ];
  31.     }])
  32.     .directive("unorderedList", function () {
  33.         return function (scope, element, attrs) {
  34.             var data = scope[attrs['unorderedList']];
  35.             if( angular.isArray(data) ){
  36.                 for(var i=0, len=data.length; i<len; i++){
  37.                     console.log(data[i].name);
  38.                 }
  39.             }
  40.         };
  41.     });
  42. </script>
  43. </html>

 打破对数据属性的依赖

         设置一个元素属性,用来动态第设置需要参加运算的键。如果属性名是以data-为前缀的,AngularJS会在生成传给连接函数的属性集合时移除这一前缀。也就是说data-list-property和list-property都会被表示为listProperty。


  
  
  1. <div unordered-list="products" list-property="name"></div>

  
  
  1. var data = scope[attrs['unorderedList']];
  2. var propertyName = attrs['listProperty'];
  3. if(angular.isArray(data)){
  4.     var listElem = angular.element("<ul>");
  5.     element.append(listElem);
  6.     for(var i=0, len=data.length; i<len; i++){
  7.         listElem.append( angular.element('<li>').text(data[i][propertyName]) );
  8.     }
  9. }       

计算表达式


  
  
  1. <div unordered-list="products" list-property="price | currency"></div>        

        添加过滤器后,自定义指令被破坏了。可以让作用域将属性值当做一个表达式进行计算。scope.$eval()接收两个参数:要计算的表达式和需要用于执行该计算的任意本地数据。


  
  
  1. listElem.append( angular.element('<li>').text(scope.$eval(propertyName, data[i])) );

处理数据变化


  
  
  1. <div class="panel-body">
  2.     <button class="btn btn-primary" ng-click="incrementPrices()">
  3.         Change Prices
  4.     </button>
  5. </div>

  
  
  1. $scope.incrementPrices = function () {
  2.     for(var i=0,len = $scope.products.length; i<len; i++){
  3.         $scope.products[i].price++;
  4.     }
  5. }
添加监听器

  
  
  1. if(angular.isArray(data)){
  2.     var listElem = angular.element("<ul>");
  3.     element.append(listElem);
  4.     for(var i=0, len=data.length; i<len; i++){
  5.         var itemElem = angular.element('<li>');
  6.         listElem.append(itemElem);
  7.         var watchFn = function (watchScope) {
  8.             return watchScope.$eval(propertyName, data[i]);
  9.         };
  10.     
  11.         scope.$watch(watchFn, function (newValue, oldValue) {
  12.             itemElem.text(newValue);
  13.         });
  14.     }
  15. }

        第一个函数(监听器函数)基于作用域中的数据计算出一个值,该函数在每次作用域发生变化时都会被调用。如果该函数的返回值发生了变化,处理函数就会被调用,这个过程就像字符串表达式方式一样。提供一个函数来监听,能够从容地面对表达式中有可能带有过滤器的数据值得情形。

        第二个监听器函数是针对$eval()计算的表达变化,来执行回调函数的。

        以上代码并不能正确显示,涉及到for循环闭包问题。


  
  
  1. for(var i=0, len=data.length; i<len; i++){
  2.     (function () {
  3.         var itemElem = angular.element('<li>');
  4.         listElem.append(itemElem);
  5.         var index = i;
  6.         var watchFn = function (watchScope) {
  7.             return watchScope.$eval(propertyName, data[index]);
  8.         };
  9.  
  10.         scope.$watch(watchFn, function (newValue, oldValue) {
  11.             itemElem.text(newValue);
  12.         });
  13.     }());
  14. }

 或者


  
  
  1. (function (i) {
  2.     var itemElem = angular.element('<li>');
  3.     listElem.append(itemElem);
  4.  
  5.     var watchFn = function (watchScope) {
  6.         return watchScope.$eval(propertyName, data[i]);
  7.     };
  8.  
  9.     scope.$watch(watchFn, function (newValue, oldValue) {
  10.         itemElem.text(newValue);
  11.     });
  12. })(i);

 jqLite

        jqLite中element()、append()等方法的参数是HTML string or DOMElement。


  
  
  1. return function (scope, element, attrs) {
  2.     var listElem = element.append("<ol>");
  3.     for (var i = 0; i < scope.names.length; i++) {
  4.         listElem.append("<li>").append("<span>").text(scope.names[i]);
  5.     }
  6. }       

        上述添加的是字符串,最后添加只有scope.names中最后一条信息。


  
  
  1. return function (scope, element, attrs) {
  2.     var listElem = angular.element("<ol>");
  3.     element.append(listElem);
  4.     for (var i = 0; i < scope.names.length; i++) {
  5.         listElem.append(angular.element("<li>")
  6.                 .append(angular.element("<span>").text(scope.names[i])));
  7.     }
  8. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值