《中级前端5.5》AngularJS Directive 的使用——自定义html组件,与controller会话,element

核心内容: 1.使用 Directive 自定义 HTML 组件; 2.Directive 与 Controller 之间的会话; 3.使用 Angular.element 操作 Dom; 

《AngularJS》5个实例详解Directive(指令)机制 http://damoqiongqiu.iteye.com/blog/1917971

 

使用 Directive 自定义 HTML 组件

 

html:

<div ng-app="app">
    <div class="hello"></div>
    <div shuxing class="yangshi"></div>
</div>

js:

 1 var app = angular.module('app', []);
 2 
 3 app.directive('hello', function(){
 4     return {
 5         restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
 6         template: '<div>Hello AngularJS</div>',
 7         replace: true,    //替换掉我们自定义的directive名称
 8         link: function() {
 9         }
10     };
11 });
12 
13 app.directive('shuxing', function(){
14     // Runs during compile
15     return {
16         restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
17         link: function() {
18             alert("我是属性");
19         }
20     };
21 });
22 
23 app.directive('yangshi', function(){
24     // Runs during compile
25     return {
26         restrict: 'C', // E = Element, A = Attribute, C = Class, M = Comment
27         link: function() {
28             alert("我在样式");
29         }
30     };
31 });

 

可以看到,<hello>这个东东已经被<div>Hello AngularJS</div>这个标签替换掉

指令声明方式选项:

 

 

Directive 与 Controller 之间的会话

 

directive中通过属性和参数调用controller:

 1 <div ng-app="app">
 2     <div ng-controller="AppCtrl">
 3         <div enter="delData()">I'm here</div>
 4     </div>
 5 </div>    
 6 
 7 <script>
 8 var app = angular.module('app', []);
 9 
10 app.controller('AppCtrl', function($scope){
11     $scope.loadMoreData = function(){
12         alert("正在加载数据...");
13     }
14     $scope.delData = function(){
15         alert("正在删除数据...");
16     }
17 })
18 
19 app.directive('enter', function(){
20         //directive中的restrict默认就是'A',即属性
21         //link可以直接返回
22     return function(scope, element, attrs){
23         element.bind('mouseenter', function(){
24             // $scope.loadMoreData();    //这样和div中直接ng-mouseenter="loadMoreData()"是一样的,没有意义
25             // scope.$apply("loadMoreData()");
26             scope.$apply(attrs.enter);    //通过div中的属性实现调用
27         })
28     }
29 })
30 </script>

 

directive之间通过require获得controller进行数据交流:

 1 <div ng-app="app">
 2     <food apple orange banana>所有食物</food>
 3     <food apple orange>所有食物</food>
 4 </div>
 5 
 6 <script>
 7 var app = angular.module('app', []);
 8 
 9 app.directive('food', function(){
10     return {
11         restrict: 'E',
12         scope : {},    //每次初始化directive,都清空scope
13         controller: function($scope){
14             $scope.foods = [];
15             this.addApple = function(){
16                 $scope.foods.push('apple');
17             }
18             this.addOrange = function(){
19                 $scope.foods.push('orange');
20             }
21             this.addBanana = function(){
22                 $scope.foods.push('banana');
23             }
24         },
25         link: function(scope, element, attrs) {    
26             element.bind('mouseenter', function(){
27                 console.log(scope.foods);
28             });
29         }
30     }
31 })
32 app.directive('apple', function(){
33     return {
34         require: 'food',    //用require获得food中的controller
35         link: function(scope, iElm, iAttrs, foodCtrl) {    
36             foodCtrl.addApple();    
37         }
38     }
39 })
40 app.directive('orange', function(){
41     return {
42         require: 'food',
43         link: function(scope, iElm, iAttrs, foodCtrl) {    
44             foodCtrl.addOrange();    
45         }
46     }
47 })
48 app.directive('banana', function(){
49     return {
50         require: 'food',
51         link: function(scope, iElm, iAttrs, foodCtrl) {    
52             foodCtrl.addBanana();    
53         }
54     }
55 })
56 </script>

访问页面:

 

关于directive里的link和controller区别?
1、执行顺序:先controller后link
2、何时使用controller:一般场景下都不想要使用controller,只需要把逻辑写在link中就可以了;用controller的场景就是该指令(假设为a)会被其他指令(假设为b)require的时候,这样就会在b指令的link函数中传入这个controller(如果require多个的话,传入的是一个数组,数组中存放的是每一个require的指令对应的controller),目的很显然是为了指令间进行交流的。

 

 

Angular.element 的用法

先看一段代码:

<div enter leave>我在这里</div>

<script>

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

app.directive('enter', function(){
    return function(scope, element, attrs){
        //console.log(element);    有很多类jQuery的方法可以使用
        element.bind('mouseenter', function(){
            element.addClass('alert-box');
        })
    }
});
app.directive('leave', function(){
    return function(scope, element, attrs){
        element.bind('mouseleave', function(){
            element.removeClass('alert-box');
        })
    }
});

</script>

效果:

1.初始状态:

2.鼠标移入状态:

3.鼠标移出状态:

 

 

可以看到,自定义好directive指令后,当我们在html中使用的时候,自动就可以执行link中的回调方法。

 

而且link中的参数都使都非常好用:

element使得link中可以直接操作自定义组件的DOM;

attrs可以获得组件中的属性值;(属性可以是调用controller中的某个方法,使用非常灵活)

当directive中require其他directive的时候,还可以获得controller引用,可以直接操作其他directive中的controller,实现directive间的通信。

 

 

下面我们来看一个稍微复杂点的element使用方法:

 1 <hello></hello>
 2 
 3 <script>
 4 
 5 app.directive('hello', function(){
 6     return {
 7         restrict: 'E',
 8         template: '<div><input class="input" ng-model="txt"><div>{{txt}}</div></div>',
 9         link: function(scope, element){
10             scope.$watch('txt', function(newValue) {
11                 if(newValue === 'error'){
12                     element.addClass('alert-box alert');
13                 }
14             });
15         }
16     }
17 })
18 
19 </script>

可以看到,element的使用方法非常灵活。

posted @ 2016-01-18 07:46  暖风叔叔  阅读(266)  评论(0)    收藏  举报