Angular之指令Directive用法详解

前端之家收集整理的这篇文章主要介绍了Angular之指令Directive用法详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

项目筹备近期开启Angular学习,指令比较难理解所以记录备案,推荐视频大漠穷秋 Angular实战 由于篇幅过长,列举大纲如下:

一、指令directive概述

指令可以对元素绑定事件监听或者改变DOM结构而使HTML拥有像jQuery一样效果具有交互性。不同于jQuery,Angular设计核心思想是通过数据与模板的绑定,摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。

几种常见指令ng-app 指令用来指定ng的作用域是在那个标签以内部分(标签) ng-repeat迭代器指令可以重复标记元素、ng-show指令可以根据条件是否显示一个元素、ng-model指令具有双向数据绑定特性、ng-controller 用来声明一个需要和数据进行绑定的模板区域

二、自定义指令directive之模式匹配restrict

直接上代码体验一把,index.html

<Meta charset="UTF-8"> Angular指令--<a href="/tag/zidingyi/" target="_blank" class="keywords">自定义</a><a href="/tag/biaoqian/" target="_blank" class="keywords">标签</a>

指令Directive.js

//调用angular对象的module方法来声明一个模块,模块的名字和ng-app的值对应

var myModule = angular.module('myModule',[]);

/* restrict 属性值说明 <推荐使用EA>

  • E--element元素

  • A--attribute 属性

  • C-class 样式类 <div class="hello">

  • M 注释

  • */

    //指令--对元素绑定事件监听或者改变DOM

    myModule.directive('hello',function(){

    return {

    restrict: 'EACM',templateUrl:'hello_Angular.html',/*template : '<p>Hello Angular</p>',*/
    
    replace: true

    }
    })

    ========================================================== restrict---匹配模式说明, 英文意思是"限制;约束;限定",这里指的是匹配我自定义标签 ========================================================== •E  元素(element)    •A  属性(attribute)  

    •C  样式类(class)  
    •M  注释 注意!!!空格(不常用)

    温馨tips: 推荐使用EC或EA匹配模式

    replace 是否替换元素的模式 replace:true浏览器DOM结构如下

    replace:false 或没有replace属性时浏览器DOM结构如下

    三、指令之嵌套变换transclude

    <html ng-app="myApp">

    <Meta charset="UTF-8">

    transclude 嵌套变换

    <script type="text/javascript" src="framework/1.3.0.14/angular.js">

    这里是内容哦.....
    这里是内容哦hello....

    <script type="text/javascript">

    var myApp = angular.module('myApp',[]);

    myApp.directive('hello',function(){

    return {
    
     restrict: 'EA',template: '<p>Hello World!!!<b ng-transclude></b></p>',transclude: true,/*嵌套变换*/
    
     replace: true /*替换*/
    
    }

    })

    四、指令directive运行原理

    五、指令配置参数说明

    var directiveDefinitionObject = {

    restrict: string,//指令的使用方式,包括标签属性,类,注释

    priority: number,//指令执行的优先级

    template: string,//指令使用的模板,用HTML字符串的形式表示

    templateUrl: string,//从指定的URL地址加载模板或<script type="text/ng-template" id="string">

    replace: bool,//是否用模板替换当前元素,若为false,则append在当前元素上

    transclude: bool,//是否将当前元素的内容转移到模板中

    scope: bool or object,//指定指令的作用域

    controller: function controllerConstructor($scope,$element,$attrs,$transclude){...},//定义与其他指令进行交互的接口函数

    require: string,//指定需要依赖的其他指令

    link: function postLink(scope,iElement,iAttrs) {...},//以编程的方式操作DOM,包括添加监听器等

    compile: function compile(tElement,tAttrs,transclude){

    return: {
    
     pre: function preLink(scope,iAttrs,controller){...},post: function postLink(scope,controller){...}
    
    }

    }//编程的方式修改DOM模板的副本,可以返回链接函数

    };

    return directiveDefinitionObject;

    });

    六、指令与控制器的交互

    index.html 如下

    <html ng-app="myApp">

    <Meta charset="UTF-8">

    Directive指令与Controller控制器交互

    <script type="text/javascript" src="framework/1.3.0.14/angular.js">

    <script type="text/javascript" src="js/Directive&Controller.js">

    <div ng-controller="myAppCtrl">

    <loader hello howToLoad="loadData()">数据加载......

    <div ng-controller="myAppCtrl2">

    <loader hello howToLoad="loadData2()">数据加载2......

    Directive&Controller.js

    myApp.controller('myAppCtrl',['$scope',function($scope){

    console.log($scope);

    $scope.loadData = function(){

    console.log('数据加载中.....');

    }

    }]);

    myApp.controller('myAppCtrl2',function($scope){

    console.log($scope);

    $scope.loadData2 = function(){

    console.log('数据加载中2.....');

    }

    }]);

    //指令与控制器之间交互

    myApp.directive('loader',function(){

    return {

    restrict: 'EA',template: '

    ',replace: true,/scope: {},独立scope/

    link: function(scope,element,attrs){

    element.bind('mouseenter',function(){

    /*这里<a href="/tag/diaoyong/" target="_blank" class="keywords">调用</a>controller中的<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>三种方式*/
    
    /*(1) scope.loadData();
    
     (2) scope.$apply('loadData()');
    
     (3) attrs.howtoload === <a href="/tag/shuxing/" target="_blank" class="keywords">属性</a>上绑定的<a href="/tag/hanshu/" target="_blank" class="keywords">函数</a><a href="/tag/mingcheng/" target="_blank" class="keywords">名称</a>*/
    
    //<a href="/tag/shuxing/" target="_blank" class="keywords">属性</a>方式 注意坑!!! howtoload 得小写
    
    scope.$apply(attrs.howtoload);

    })

    }

    }

    })

    实现的效果是当鼠标滑过div元素时,调用一个加载数据的方法

    上述例子中定义了两个控制器,然后两个控制器中都使用了loader指令,并且,每个指令中都有一个参数 howToLoad .

    关于指令中的 link ,上面介绍运行机制中可以了解到,link: function postLink(scope,attrs) {...}是用来操作dom和绑定监听事件的。

    link中会有三个参数:scope(指令所属的控制器中的 $scope 对象)、element(指令所属dom元素)、attrs(dom元素所传的参数

    如howToLoad 参数给的值 loadData()

    然后对于如何调用所需函数,有两种方法

    1> scope.loadData() 两个控制器方法不一致时,就不能用了

    2> scope.$apply() $apply()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。

    明确对于控制器ng-controller都会创建属于自己独立的scope;对于指令若无scope:{}声明会继承控制器中的scope

    七、指令与指令的交互

    index.html

    <html ng-app="myModule">

    <Meta charset="UTF-8">

    directive指令与directive指令之间的交互

    <script type="text/javascript" src="framework/1.3.0.14/angular.js">

    <script type="text/javascript" src="js/Directive&Directive.js">

    <div class="row">

    <div class="col-md-3">

    <superman strength>动感超人---力量</superman>

    <div class="row">

    <div class="col-md-3">

    <superman strength speed>动感超人2---力量+敏捷</superman>

    <div class="row">

    <div class="col-md-3">

    <superman strength speed light>动感超人3---力量+敏捷+发光</superman>

    Directive&Directive.js

    //指令与指令之间交互

    myModule.directive('superman',function(){

    return {

    scope: {},/独立作用域/

    restrict: 'AE',template: '',controller: function($scope){ /暴露controller里面方法/

    $scope.abilities = [];

    this.addStrength = function(){

    $scope.abilities.push('strength'); 

    };

    this.addSpeed = function(){

    $scope.abilities.push('speed');

    };

    this.addLight = function(){

    $scope.abilities.push('light');

    };

    },link: function(scope,attrs,supermanCtr){

    element.addClass = "btn btn-primary";

    element.bind('mouseenter',function(){

    console.log(scope.abilities);

    })

    }

    }

    })

    myModule.directive('strength',function(){

    return {

    require: "^superman",/require参数指明需要依赖的指令/

    link: function(scope,supermanCtr){

    supermanCtr.addStrength();

    }

    }

    });

    myModule.directive('speed',supermanCtr){

    supermanCtr.addSpeed();

    }

    }

    });

    myModule.directive('light',supermanCtr){

    supermanCtr.addLight();

    }

    }

    });

    *require参数指明需要依赖的指令

    *指令中的controller相当于暴露里面方法,便于指令复用

    八、scope作用域绑定策略

    scope “@” 把当前属性作为字符串传值

    <html ng-app="myModule">

    <Meta charset="UTF-8">

    scope绑值策略一.'@'把当前<a href="/tag/shuxing/" target="_blank" class="keywords">属性</a>作为字符串传值

    <script type="text/javascript" src="framework/1.3.0.14/angular.js">

    <script type="text/javascript" src="js/Scope@.js">

    <div ng-controller="myAppCtrl">

    <drink flavor="{{ctrFlavor}}">

    Scope@.js

    myModule.controller('myAppCtrl',function($scope){

    console.log($scope);

    $scope.ctrFlavor = "百事可乐";

    }]);

    myModule.directive('drink',function(){

    return {

    restrict: 'AE',scope: { /独立scope作用域/

    flavor: '@'

    },replace:true,template: '

    {{flavor}}

    '

    //使用link进行指令和控制器两个作用域中数据的绑定。

    //如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定

    /*,link:function(scope,attrs){

    element.bind('mouseenter',function(){

    })

    scope.flavor = attrs.flavor;

    }*/

    }

    })

    scope “=” 与父scope属性进行双向绑定

    index.html

    <html ng-app="myModule">

    <Meta charset="UTF-8">

    scope绑值策略二.'='与父scope中的<a href="/tag/shuxing/" target="_blank" class="keywords">属性</a>进行双向绑定

    <script type="text/javascript" src="js/scope=.js">

    <div ng-controller="myModuleCtrl" class="col-sm-6">

    {{describe}}

    Ctrl--控制器:


    {{ctrFlavor}}

    Directive--指令:

    <drink flavor="ctrFlavor">

    {{flavor}}

    scope=.js

    myModule.controller('myModuleCtrl',function($scope){

    $scope.describe = "scope绑值策略二.=与父scope中的属性进行双向绑定";

    $scope.ctrFlavor = "可口可乐";

    }]);

    //=与父scope中的属性进行双向绑定

    myModule.directive('drink',scope: { /ng-isolate-scope 隔离作用域/

    flavor : '='

    },template: ''

    /replace:true/

    }

    });

    这个例子中有两个输入框,第一个绑定了myModuleCtrl控制器中的scope对象的ctrlFlavor 属性

    第二个绑定的是指令中的flavor属性。但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,

    与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。 简单理解为把两个存放数据仓库给相等 A1 == B1

    scope& '&'传递一个来自父scope的函数,稍后调用

    index.html

    <html ng-app="myModule">

    <Meta charset="UTF-8">

    scope绑值策略三.'&'传递一个来自父scope的<a href="/tag/hanshu/" target="_blank" class="keywords">函数</a>,稍后<a href="/tag/diaoyong/" target="_blank" class="keywords">调用</a>

    <script type="text/javascript" src="js/scope&.js">

    <div ng-controller="myModuleCtrl">

    <greeting greet="sayHello(name)">@H718301@

    <greeting greet="sayHello(name)">@H718301@

    <greeting greet="sayHello(name)">@H718301@

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

    <div class="col-sm-12 container">

    <form role = "form"&gt;
    
     <div class = "form-group"&gt; 
    
      <input type="text" class="form-control" ng-model="userName" />
    
      <button class="btn btn-primary" ng-click="greet({name:userName})"&gt;Greeting</button>
    
     </div> 
    
    </form>

    scope&.js

    $scope.sayHello = function(name){

    console.log('Hello'+name);

    }

    }]);

    myModule.directive('greeting',scope: { /'&'传递一个来自父scope的函数,稍后调用/

    greet : '&'

    },templateUrl: 'sayHello.html'

    }

    });

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

    angularangularangularjsdirectivedirective用法

    猜你在找的JavaScript相关文章