Angular指令中几个重要属性的具体用法

Angular指令

    定义一个指令的方法非常简单,只需要调用`directive`方法即可:
    var app=angular.module('myapp',[]);
    app.directive(name,fn)

1. 基础指令

    var app=angular.module('myapp',[]);
        app.run(function($templateCache){
            $templateCache.put('cache','<h3>模板内容来源于缓存</h3>')
        });
        app.directive('tsHello',function(){
            return{
                restrict:'EAC',
                template:'<h3>Hello,directive</h3>'
            }
        })
        app.directive('tsTplfile',function(){
            return{
                restrict:'EAC',
                templateUrl:'/static/tpl.html'
            }
        });
        app.directive('tsTplscript',function(){
            return {
                restrict:'EAC',
                templateUrl:'tpl',
                replace:true
            }
        });
        //templateUrl属性值是添加的缓存名称,加速文件访问
        app.directive('tsTplcache',function(){
            return{
                restrict:'EAC',
                templateUrl:'cache'
            }
        })
    </script>

2. 重要指令

2.1 transclude

 <script type="text/ng-template" id='tpl'> <div> <input type="text" ng-model='text' /> <div ng-transclude></div> </div> </script> <ts-tplscript>{{text}}</ts-tplscript> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsTplscript',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true } }); </script>

  关于transclude更加详细的介绍,参见另外一篇文章

  link属性的值是一个函数,在该函数中可以操控DOM元素的对象,包括绑定元素的各类事件,定义事件触发时执行的内容等:
link:function(scope,iEle,iAttrs)

  link 函数包括3个主要的参数,其中,scope参数表示指令所在的作用域,它的功能与页面中控制器注入的作用域是相同的,iEle参数表示指令中的元素,该元素可以通过Angular内部封装的jqLite进行调用,jqLite相当于是一个压缩版的jQuery,包含了主要的元素操作API,在语法上与jQuery类似,iAttrs参数表示指令元素的属性集合,通过这个参数可以获取元素中的各类属性。

 <script type="text/ng-template" id='tpl'> <button>单击按钮</button> </script> <div> <ts-tplscript></ts-tplscript> <div>{{content}}</div> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsTplscript',function(){ return { restrict:'EAC', templateUrl:'tpl', replace:true, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.content='这是点击后的内容'; }) iAttrs.$$element[0].disabled=true;//这里也可以替换为this.disabled=true; }); } } }); </script>

  自定义tsTplscript指令时,在指令返回的对象中添加了link属性,用于绑定和执行DOM元素的各类事件,在属性值执行的函数中,添加scope,iEle,iAttrs三个参数,在指令执行的过程中,由于指令中并没有定义scope属性,因此,scope参数默认就是元素外层父级scope属性,即控制器注入的$scope属性。
  此外,iEle参数就是被指令模板替换后的<button>元素,由于在Angular中引入了jqLite,因此可以直接调用bind方法绑定元素的各类事件,在执行事件函数的时候,调用了scope属性的$apply方法,它的功能是在执行完方法中的函数之后,重新渲染页面视图。
  iAttrs参数是指令元素的属性集合,$$element则表示与属性对应的元素集合,该集合是一个数组。

2.3 compile

 <div ng-controller='myController'> <ts-a> <ts-b> {{tip}} </ts-b> </ts-a> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.controller('myController',function($scope){ $scope.tip='跟踪compile执行过程 '; }); app.directive('tsA',function(){ return { restrict:'EAC', compile:function(tEle,tAttrs,trans){ console.log('正在编译A指令'); //返回一个对象时,对象中包含两个名为`pre`和`post`的方法函数 return { pre:function(scope,iEle,iAttrs){ console.log('正在执行A中的pre函数'); }, post:function(scope,iEle,iAttrs){ console.log('正在执行A中的post函数'); } } } } }); app.directive('tsB',function(){ return { compile:function(tEle,tAttrs,trans){ console.log('正在编译B指令'); return{ pre:function(scope,iEle,iAttrs){ console.log('正在执行B中的pre函数'); }, post:function(scope,iEle,iAttrs){ console.log('正在执行B中的post函数'); } } } } }) </script>

控制台依次输出:

    正在编译A指令
    正在编译B指令
    正在执行A中的pre函数
    正在执行B中的pre函数
    正在执行B中的post函数
    正在执行A中的post函数

2.4 scope

2.4.1 当scope值是布尔类型
  scope属性自定义指令时,默认值就是布尔类型的,初始值为false,在这种情况下,指令中的作用域就是指令元素所在的作用域,如果scope属性值为false,表示不创建新的作用域,直接继承父级作用域,二者数据完全相同,一方有变化,另外一方面将会自动变化。
  如果scope属性值为true,表示子作用域是独立创建的,当它的内容发生变化时,并不会修改父作用域中的内容,不仅如此,一旦某个属性被子作用域进行了重置,那么,即使父作用域中的内容变化了,子作用域对应的内容也不会随之变化。

 <script type="text/ng-template" id='tpl'> <div>{{message}}</div> <button ng-transclude></button> </script> <div> <input type="text" ng-model='message' /> <ts-message>固定</ts-message> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsMessage',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true, scope:true, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.message='这是单击按钮后的值。' }) }) } } }); </script>

  在单击按钮之前,子作用域中的值随父作用域改变,当单击按钮之后,手动重置了子作用域中的’message’遍历,但与变量绑定的父作用域的内容并没有变化,并且子作用域也不再随父作用域发生变化。

2.4.2 当scope值是对象
  如果将scope属性值设置成一个JSON对象,那么父作用域与子作用域完全独立,不存在任何关联。
  当指令中的scope属性值是JSON对象时,如果子作用域需要添加属性,必须先添加指令中的link函数,然后通过函数中的scope对象进行添加,如果在子作用域中,要绑定或调用父父作用域中的属性和方法,则需要在scope属性对应的JSON对象值中添加绑定策略。
  严格来说,在JSON对象中添加的有3种绑定策略:@ = &

  1. @
    @绑定与将scope值设为true,有许多相同的地方,唯一不同之处在于,@绑定在子作用域充值属性之后,再返回修改父作用域对应属性内容时,子作用域对应的属性,同样还是会随之发生变化,而使用scope:true,则不会发生这一步。
  2. =
    =绑定的功能是创建一个父与子作用域可以同时共享的属性,即当父作用域修改了该属性,子作用域也随之变化,反之亦然,两个作用域间完全共享和同步。
  3. &
    &绑定的功能是可以在独立的子作用域中直接调用父作用域的方法,在调用时可以向函数传递参数,这种功能的好处在于,避免重复编写功能相同的代码,只需要进行简单的绑定设置,就可以使指令执行后,轻松调用控制器中的方法。
 <script type="text/ng-template" id='tpl'> <div> <span>姓名:{{textName}}</span> <span>年龄:{{textAge}}</span> </div> <button ng-transclude></button> </script> <div ng-controller="myController"> 姓名:<input type="text" ng-model='text_name' /><br> 年龄:<input type="text" ng-model='text_age' /><br> <div>{{tip}}</div> <ts-json a-attr="{{text_name}}" b-attr="text_age" reset="reSet()">重置</ts-json> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.controller('myController',function($scope){ $scope.reSet=function(){ $scope.tip='姓名与年龄重置成功!'; } }); app.directive('tsJson',function(){ return { restrict:'EAC', templateUrl:'tpl', transclude:true, scope:{ textName:'@aAttr', textAge:'=bAttr', reSet:'&reset' }, link:function(scope,iEle,iAttrs){ iEle.bind('click',function(){ scope.$apply(function(){ scope.reSet(); scope.textName='张三'; scope.textAge='20'; }) }) } } }); </script>

绑定的过程:

  先在指令元素中创建a-attrb-attr属性,由于HTML不区分大小写,因此使用-隔开。
  需要注意的是:由于在指令中绑定策略不同,在指令元素中,属性绑定属性值也会有些变化,使用@绑定的属性,绑定属性值的方式为双大括号{{}},而使用=绑定的属性,绑定属性值的方式为等于号=,不需要双大括号.

2.5 require和controller

当一个子元素需要与一个父元素指令通信时,就需要添加并使用这两个属性值。

 <div> <ts-parent> <div>{{ptip}}</div> <ts-child> <div>{{ctip}}</div> </ts-child> <button ng-click='click()'>换位</button> </ts-parent> </div> <script type="text/javascript"> var app=angular.module('myapp',[]); app.directive('tsParent',function(){ return { restrict:'EAC', controller:function($scope,$compile,$http){ this.addChild=function(c){ $scope.ptip='今天天气不错!'; $scope.click=function(){ $scope.tmp=$scope.ptip; $scope.ptip=c.ctip; c.ctip=$scope.tmp; } } } } }); app.directive('tsChild',function(){ return { restrict:'EAC', require:'^?tsParent', link:function(scope,iEle,iAttrs,ctrl){ scope.ctip='气温正好18摄氏度'; ctrl.addChild(scope); } } }) </script>

Angular指令中还有其他许多元素,具体可见另外一篇文章

你可能感兴趣的:(Angular)