菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
383
0

Ⅵ.AngularJS的点点滴滴-- 指令

原创
05/13 14:22
阅读数 91797

指令


基本用法

<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
<div ng-controller="detail">
    <input type="text" ng-model="test">
    <label ui-a="test"></label>
</div>
<script>
var app = angular.module('app', [])
.directive('uiA',function() {
    return function(scope, element, attr) {
        element.addClass('ng-binding').data('$binding', attr.uiA);
        scope.$watch(attr.uiA,function uiAWatchAction(value) {
            element.html(value + "directive" || '');
        });
    }
  }).controller('detail', ['$scope',function($scope) {
    $scope.test = 1
}]);
angular.bootstrap(document, ['app']);
</script>
</html>

这个是最基本的用法其中的指令匹配遵循以下原则

  1. 使用指令时可以在元素或者属性的前面可以添加x-data-
  2. 忽略:,-,_分隔符,并且忽略大小写

或者用$compileProviderdirective方法创建指令,方法如下

angular.module('app', []).config(['$compileProvider',
function($compileProvider) {
    $compileProvider.directive({
        uiA: function() {
            return function(scope, element, attr) {
                element.addClass('ng-binding').data('$binding', attr.uiA);
                scope.$watch(attr.uiA,
                function uiAWatchAction(value) {
                    element.html(value || '');
                });
            }
        }
    });
}]);

其中scope.$watch方法是监听对象的属性是否改变,里面的三个参数为

  1. scope 是angularjs作用域对象
  2. element 是指令匹配的jqlite对象
  3. attrs 是存放着这个对象的属性和属性操作的对象

高级用法(上面都是返回方法,这次是返回对象)


angular.module('app', []).config(['$compileProvider',
function($compileProvider) {
    $compileProvider.directive({
        uiA: function() {
            return {
                priority: 0,
                terminal:true,              
                template:'',
                templateUrl:'',
                restrict:'AE',
                scope: {
                  customer: '='
                }, 
                replcae:true,
                link: {                    
                 pre: function preLink(scope, iElement, iAttrs, controller) { 

                 },
                 post: function postLink(scope, iElement, iAttrs, controller) { 
                  iElement.addClass('ng-binding').data('$binding', iAttrs.uiA);
                  scope.$watch(iAttrs.uiA,function uiAWatchAction(value) {
                      element.html(value || '');
                  });
                 }
                },
                compile: function compile(tElement, tAttrs, transclude) {
                  return {
                    pre: function preLink(scope, iElement, iAttrs, controller) { ... },
                    post: function postLink(scope, iElement, iAttrs, controller) { ... }
                  }
                },
                require:'',            
                transclude:true,              
                controlleras:'a',
                controller: function($scope, $element, $attrs){

                }            
            }
        }
    });
}]);
  1. priority权重默认是0,当包含多个指令的时候按照权重从大开始,其中Pre-link方法为从大到小, post-link方法从小到大。当权限相同的时候目前测试结果是按照顺序
  2. terminal当设置为true的时候比当前权重低的指令会失效,相同的会执行
  3. templatetemplateUrl的功能和前面的路由里面的一样
  4. replcaetrue会替换当前指令的元素,false会替换元素innerHTML属性, 使用的时候模板必须有根节点,感觉只有restrictE时有效
  5. restrict,AE即匹配属性和元素名称,其中A为仅匹配属性,E为仅匹配元素名称,M匹配注释
    <html>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
    <div g-controller="detail">
     <ui-a info="test"></ui-a>
    </div>
    <script>
    angular.module('app', []).config(['$compileProvider',
    function($compileProvider) {
     $compileProvider.directive({
         uiA: function() {
             return {
                 restrict: 'E',
                 replace:true,
                 scope: {
                   info: '=info'
                 },
                 template:'<div>{{info.name}},{{info.sex}}</div>' 
             }
         }
     });
    }]).controller('detail', ['$scope',
    function($scope) {
     $scope.test = {name:'a',sex:'1'};
    }]);
    angular.bootstrap(document, ['app']);
    </script>
    </html>
  6. scope设置绑定指令的上下文,使用的时候必须要restrictE, 当设置为true的时候指令之间是不共用一个上下文,应该默认为false

    1. {info: '=info'}获取属性为info的对象
    2. {info: '@info'}获取属性为info的值并且标签里面写成info="{{test}}
    3. {info: '&info'}里面写表达式,并且可以赋予参数
      <html>
      <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
      <div ng-controller="detail">
      {{count}}
      <ui-a info="count = count + amount"></ui-a>
      </div>
      <script>
      angular.module('app', []).config(['$compileProvider',
      function($compileProvider) {
      $compileProvider.directive({
        uiA: function() {
            return {
                restrict: 'E',
                scope: {
                  info: '&info'
                },
                controller:function($scope){
                   $scope.info({amount:11});
                }
            }
        }
      });
      }]).controller('detail', ['$scope',
      function($scope) {
      $scope.count =1;
      }]);
      angular.bootstrap(document, ['app']);
      </script>
      </html>
  7. controller为当前指令中的控制器对象,里面的第四个参数$transclude可以 设置transclude的元素和compile的第三个参数一样 4.transclude当设置为ture的时候指令原来的html插入到有ng-transclude的属性的元素, 默认为false,当设置为element的时候还未知...

    <html>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
    <div>
     <ui-a>Check out the contents</ui-a>
    </div>
    <script>
    angular.module('app', []).config(['$compileProvider',
    function($compileProvider) {
     $compileProvider.directive({
         uiA: function() {
             return {
                 restrict: 'E',
                 transclude: true,
                 template: '<div class="alert" ng-transclude></div>'
             }
         }
     });
    }]);
    angular.bootstrap(document, ['app']);
    </script>
    </html>
  8. require用于请求其他的指令,在link的第四个参数注入, ^表示在dom模型上面的上一个节点,没有加表示是在同一个元素上面, 同级的不知何解,当前前面加上?表示不存在的时候不报错, 调用另一个控制器只能是声明this后的,如以下代码改成$scope.a=1则调用不到
    <html>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
    <div>
     <ui-b> 
        <ui-a></ui-a>
     </ui-b>
    </div>
    <script>
    angular.module('app', []).config(['$compileProvider',
    function($compileProvider) {
     $compileProvider.directive({
        uiB: function() {
             return {
                 restrict: 'E',
                 transclude:true,          
                 controller: function($scope){
                   this.a=1;
                 },
                 template: '<div ng-transclude></div>'
             }
         },
         uiA: function() {
             return {
                 require: '^uiB',
                 restrict: 'E',  
                 link: function(scope, element, attrs,uiBCtrl) {
                   console.log(uiBCtrl.a);
                 },
                 template: ''
             }
         }
     });      
    }]);
    angular.bootstrap(document, ['app']);
    </script>
    </html>
  9. controlleras控制器的别名
  10. link里面的post方法就是前面的基本用法,如果存在compile,则link失效, 其中pre为连接前,post为连接后
  11. compile主要用来处理模板的DOM ,返回的对象是一个link
<html  ng-app="compile"><script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
<div ng-controller="Ctrl">
      <input ng-model="name"> <br>
      <textarea ng-model="html"></textarea> <br>
      <div compile="html"></div>
</div>
<script>
angular.module('compile', [], function($compileProvider) { 
  $compileProvider.directive('compile', function($compile) {
    //新建一个link方法
    return function(scope, element, attrs) {
      scope.$watch(
        function(scope) {
          //判断编译的表达式是否改变
          return scope.$eval(attrs.compile);
        },
        function(value) {
          //当编译的表达式改变重写
          element.html(value);
          //获得控制器的上下文以及表达式重新编译
          $compile(element.contents())(scope);
        }
      );
    };
  })
});

function Ctrl($scope) {
  $scope.name = 'Angular';
  $scope.html = 'Hello {{name}}';
}
</script>
</html>

发表评论

0/200
383 点赞
0 评论
收藏