• AngularJS开发之_指令


    指令是什么?    指令是我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML关联着的指令会被检测到,并且被执行。这使得指令可以为DOM指定行为,或者改变它。

    1.指令的匹配模式

    index.html :
     1 <!doctype html>
     2 <html ng-app="MyModule">
     3     <head>
     4         <meta charset="utf-8">
     5     </head>
     6     <body>
     7         <hello></hello>
     8         <div hello></div>
     9         <div class="hello"></div>
    10         <!-- directive:hello -->
    11         <div></div>
    12     </body>
    13     <script src="framework/angular-1.3.0.14/angular.js"></script>
    14     <script src="HelloAngular_Directive.js"></script>
    15 </html>
    helloAngular_Directive.js :
    1 var myModule = angular.module("MyModule", []);
    2 myModule.directive("hello", function() {
    3     return {
    4         restrict: 'AEMC',
    5         template: '<div>Hi everyone!</div>',
    6         replace: true
    7     }
    8 });
    html中包含五个元素,其中一个是注释的元素,JS中定义了一个模块和模块的指令。
    OK,不要急,先来看一下 directive 是什么意思,directive的意思是指令,顾名思义,定义一个指令,名字叫 “hello”.
     
    首先,看一下 restrict  ,  restrict的意思是限制,约束。也就是要讲的指令的匹配模式,共有四种:
    (1)E: 元素(即html中的<hello></hello>);
    (2)A(默认) :属性 (<div hello></div>);
    (3)C: 样式类(<div class="hello"></div>)
    (4)M: 注释(<!-- directive:hello -->)
     
    常用 A E , 推荐使用这两个。下图就是匹配到的指令元素,并替换了元素的内容,至于怎么替换的内容,继续往下看。
     
     
     
    接下来,看一下 template ,template的意思是模板,也就是要替换的内容。但是在js中组织和拼接div这些元素的代码,很费劲的。怎么办呢。有办法,那就是 templateUrl, 把要替换的元素内容写到一个页面里面。嗯如下所示:
    1 var myModule = angular.module("MyModule", []);
    2 myModule.directive("hello", function() {
    3     return {
    4         restrict: 'AECM',
    5         templateUrl: 'hello.html',
    6         replace: true
    7     }
    8 });

    如果我们想要在别的指令中也是用这个hello.html怎么办,那么就有出现了一个缓存的解决办法。看下面的 run 方法在加载完所有模块后,只执行一次,然后把模板缓存起来,当有指令需要调用时,就调用 $templateCache.get().
     1 var myModule = angular.module("MyModule", []);
     2 //注射器加载完所有模块时,此方法执行一次
     3 myModule.run(function($templateCache){
     4     $templateCache.put("hello.html","<div>Hello everyone!!!!!!</div>");
     5 });
     6 myModule.directive("hello", function($templateCache) {
     7     return {
     8         restrict: 'AECM',
     9         template: $templateCache.get("hello.html"),
    10         replace: true
    11     }
    12 });
     
    接下来,再看一下 replace(”替换“),replace:true 会替换元素的内容。但是不想替换内容只是想添加一个内容呢,,没事,,还有 transclude 
    1 var myModule = angular.module("MyModule", []);
    2 myModule.directive("hello", function() {
    3     return {
    4         restrict:"AE",
    5         transclude:true,
    6         template:"<div>Hello everyone!<div ng-transclude></div></div>"
    7     } 
    8 });

     
    最后介绍一下AngularJS的运行机制:
     
     

    2.指令和控制器的交互。

    index.html :
     1 <!doctype html>
     2 <html ng-app="MyModule">
     3     <head>
     4         <meta charset="utf-8">
     5     </head>
     6     <body>
     7         <div ng-controller="MyCtrl">
     8             <loader howToLoad="loadData()">滑动加载</loader>
     9         </div>
    10         <div ng-controller="MyCtrl2">
    11             <loader howToLoad="loadData2()">滑动加载</loader>
    12         </div>
    13     </body>
    14     <script src="framework/angular-1.3.0.14/angular.js"></script>
    15     <script src="Directive&Controller.js"></script>
    16 </html>

    Directive&Controller.js :

     1 var myModule = angular.module("MyModule", []);
     2 myModule.controller('MyCtrl', ['$scope', function($scope){
     3     $scope.loadData=function(){
     4         console.log("加载数据中...");
     5     }
     6 }]);
     7 myModule.controller('MyCtrl2', ['$scope', function($scope){
     8     $scope.loadData2=function(){
     9         console.log("加载数据中...22222");
    10     }
    11 }]);
    12 myModule.directive("loader", function() {
    13     return {
    14         restrict:"AE",
    15         link:function(scope,element,attrs){
    16             element.bind('mouseenter', function(event) {
    17                 //(1)scope.loadData();
    18                 //(2)scope.$apply("loadData()");
    19                 // 注意这里的坑,howToLoad会被转换成小写的howtoload
    20                 scope.$apply(attrs.howtoload);
    21             });
    22         }
    23     } 
    24 });

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

    hmtl中我们定义了两个控制器,然后两个控制器中都使用了loader指令,并且,每个指令中都有一个参数 howToLoad .
    关于指令中的 link ,上面介绍运行机制是已经看到了,是用来操作dom和绑定监听事件的。link中会有三个参数:scope(指令所属的控制器中的 $scope 对象)、element(指令所属dom元素)、attrs(dom元素所传的参数,如howToLoad 参数给的值 loadData()).
     
    然后对于如何调用所需函数,有两种方法:
    (1)scope.loadData() ,这种方法是有局限的,如,MyCtrl1 控制器中的指令所调用的方法是MyCtrl1控制器中所定义的loadData() 方法,但是MyCtrl2就会报错了,因为没有loadData().       所有就有了另个一个方法。
    (2)scope.$apply() , $apply()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。
     

    3.指令间的交互。

    index.html :
     1 <!doctype html>
     2 <html ng-app="MyModule">
     3 <head>
     4     <meta charset="utf-8">
     5     <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
     6     <script src="framework/angular-1.3.0.14/angular.js"></script>
     7     <script src="Directive&Directive.js"></script>
     8 </head>
     9 <body>
    10     <div class="row">
    11         <div class="col-md-3">
    12             <superman strength>动感超人---力量</superman>
    13         </div>
    14     </div>
    15     <div class="row">
    16         <div class="col-md-3">
    17             <superman strength speed>动感超人2---力量+敏捷</superman>
    18         </div>
    19     </div>
    20     <div class="row">
    21         <div class="col-md-3">
    22             <superman strength speed light>动感超人3---力量+敏捷+发光</superman>
    23         </div>
    24     </div>
    25 </body>
    26 </html>

    Directive&Directive.js :
     1 var myModule = angular.module("MyModule", []);
     2 myModule.directive("superman", function() {
     3     return {
     4         scope: {},//独立作用域
     5         restrict: 'AE',
     6         controller: function($scope) {
     7             $scope.abilities = [];
     8             this.addStrength = function() {
     9                 $scope.abilities.push("strength");
    10             };
    11             this.addSpeed = function() {
    12                 $scope.abilities.push("speed");
    13             };
    14             this.addLight = function() {
    15                 $scope.abilities.push("light");
    16             };
    17         },
    18         link: function(scope, element, attrs) {
    19             element.addClass('btn btn-primary');
    20             element.bind("mouseenter", function() {
    21                 console.log(scope.abilities);
    22             });
    23         }
    24     }
    25 });
    26 myModule.directive("strength", function() {
    27     return {
    28         require: '^superman',
    29         link: function(scope, element, attrs, supermanCtrl) {
    30             supermanCtrl.addStrength();
    31         }
    32     }
    33 });
    34 myModule.directive("speed", function() {
    35     return {
    36         require: '^superman',
    37         link: function(scope, element, attrs, supermanCtrl) {
    38             supermanCtrl.addSpeed();
    39         }
    40     }
    41 });
    42 myModule.directive("light", function() {
    43     return {
    44         require: '^superman',
    45         link: function(scope, element, attrs, supermanCtrl) {
    46             supermanCtrl.addLight();
    47         }
    48     }
    49 });
    定义了一个superman的指令和另外三个指令,分别是strength、speed、light、
    后面三个指令都有一个 require 参数,是指都依赖superman指令,link中的最后一个参数就是superman指令的引用。
     

    4.scope("作用域") 的绑定策略。

    scope的绑定策略有三种:
    (1)@ :把当前属性作为字符串传值。还可以绑定来自外层scope的值,在属性值中插入{{}}即可。
    (2)= :与父scope中的属性进行双向绑定。
    (3)& :传递一个来自父scope的函数,稍后调用。
     
    index.html :
     1 <!doctype html>
     2 <html ng-app="MyModule">
     3     <head>
     4         <meta charset="utf-8">
     5         <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
     6     </head>
     7     <body>
     8         <div ng-controller="MyCtrl">
     9             <drink flavor="{{ctrlFlavor}}"></drink>
    10         </div>
    11     </body>
    12     <script src="framework/angular-1.3.0.14/angular.js"></script>
    13     <script src="ScopeAt.js"></script>
    14 </html>

    ScopeAt.js :

     1 var myModule = angular.module("MyModule", []);
     2 myModule.controller('MyCtrl', ['$scope', function($scope){
     3     $scope.ctrlFlavor="百威";
     4 }])
     5 myModule.directive("drink", function() {
     6     return {
     7         restrict:'AE',
     8         scope:{
     9             flavor:'@'
    10         },
    11         template:"<div>{{flavor}}</div>"
    12          //,
    13          //link:function(scope,element,attrs){
    14          //    scope.flavor=attrs.flavor;
    15          //}
    16     }
    17 });

    使用link进行指令和控制器两个作用域中数据的绑定。如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定。

     
    接下来看scope 的 ”=“ 绑定策略:
    1         <div ng-controller="MyCtrl">
    2             Ctrl:
    3             <br>
    4             <input type="text" ng-model="ctrlFlavor">
    5             <br>
    6             Directive:
    7             <br>
    8             <drink flavor="ctrlFlavor"></drink>
    9         </div>
     1 var myModule = angular.module("MyModule", []);
     2 myModule.controller('MyCtrl', ['$scope', function($scope){
     3     $scope.ctrlFlavor="百威";
     4 }])
     5 myModule.directive("drink", function() {
     6     return {
     7         restrict:'AE',
     8         scope:{
     9             flavor:'='
    10         },
    11         template:'<input type="text" ng-model="flavor"/>'
    12     }
    13 });

    这个例子中有两个输入框,第一个绑定了MyCtrl控制器中的scope对象的ctrlFlavor 属性。第二个绑定的是指令中的flavor属性。 但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。

     
    最后来看一下 scope 的 ”&“ 绑定策略:
    index.html :
    1     <body>
    2         <div ng-controller="MyCtrl">
    3             <greeting greet="sayHello(name)"></greeting>
    4             <greeting greet="sayHello(name)"></greeting>
    5             <greeting greet="sayHello(name)"></greeting>
    6         </div>
    7     </body>
     1 var myModule = angular.module("MyModule", []);
     2 myModule.controller('MyCtrl', ['$scope', function($scope){
     3     $scope.sayHello=function(name){
     4         alert("Hello "+name);
     5     }
     6 }])
     7 myModule.directive("greeting", function() {
     8     return {
     9         restrict:'AE',
    10         scope:{
    11             greet:'&'
    12         },
    13         template:'<input type="text" ng-model="userName" /><br/>'+
    14                  '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>'
    15     }
    16 });

    点击按钮 会调用greet()函数,在前面html中已经指定了greet要绑定sayHello()函数,函数的参数来绑定 ng-model 的 输入框。

     

    4.AngularJS内置指令。

    不同版本的内置指令数目不同,详细的看官方API(----api----)
     

    5.Angular-UI

     
     
     复杂的指令终于结束了,Angular-UI封装了很多好的指令可以直接使用。省得自己挨个再写,费劲。关于详细的一些指令的用法,多看看API ,很好学。
    希望自己越来越厉害,全能型人才即将诞生。哈哈哈哈!!
     
     
  • 相关阅读:
    简单分析实现运维利器---web远程ssh终端录像回放libl
    利用kite对视频流应用进行压力测试
    Springboot 启动扩展
    SpringBoot 自动配置原理
    idea springboot没有启动项,或启动时找不到或无法加载主类
    Elasticsearch、Kibana、elasticsearch-analysis-ik 版本下载地址
    Springboot 操作Elasticsearch 方式二 【rest-high-level-client】
    Elasticsearch 安装x-pack之后,无法连接head问题
    ES版本是向下兼容的,springboot连接ES,可以用低版本客户端
    ES安装elasticsearch-head-master插件
  • 原文地址:https://www.cnblogs.com/xinxingyu/p/4775004.html
Copyright © 2020-2023  润新知