1.angular中的指令 #

1.1 创建指令 #

<my-dire></my-dire>
var app = angular.module('appModule',[]);
app.directive('myDire',function () {
    return {

    }
});

1.2 模板 #

var app = angular.module('appModule',[]);
app.directive('myDire',function () {
    return {
+       template:'<div>Hello</div>'   
    }
});

1.3 transclude #

保留指令中的内容

<my-dire>world</my-dire>
return {
+    transclude:true,
-    template:'<div>Hello</div>'
+    template:'<div>Hello <span ng-transclude></span></div>'
}

1.3.1 面板 #

引入bootstrap

<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">

增加panel.html

<div class="panel panel-default">
  <div class="panel-heading">这是一个面板</div>
  <div class="panel-body" ng-transclude>
  </div>
</div>

修改指令代码

return {
    transclude:true,
+   templateUrl:'panel.html',
}

1.4 link函数 #

link函数是用来链接视图和scope

  1. scope:当前作用域
  2. element:jq对象
  3. attrs:当前指令上的属性
return {
       transclude:true,
       templateUrl:'panel.html',
+      link: function (scope,element,attrs) {
+                      
+      }
}

1.4.1 给面板增加传入的标题 #

增加title属性

<my-dire title="这是头部">这是一个面板,helloAngular</my-dire>

增加属性值

<div class="panel panel-default">
+    <div class="panel-heading">{{title}}</div>
     <div class="panel-body" ng-transclude></div>
</div>

声明标题

return{
    link: function (scope,element,attrs) {
+      scope.title = attrs["title"];
    }
}

1.5 独立作用域 #

可以为当前指令设置独立作用域

return {
+  scope:true,
}

1.6 动态引用数据 #

1.6.1 "@"引用字符串 #

指令和作用域间的交互 声明控制器

app.controller('appCtrl',function ($scope) {
    $scope.title = [
        {name:'第一个面板'},
        {name:'第二个面板'}
    ]
});

挂载scope上的属性

<my-dire title="{{title[0].name}}">这是一个面板,helloAngular</my-dire>
<my-dire title="{{title[1].name}}">这是二个面板,helloAngular</my-dire>

在当前作用域下声明title属性,引用对应的值

return {
    transclude:true,
    templateUrl:'panel.html',
    scope:{
        title:'@'
    }
}

1.6.2 "="引用scope上的属性 #

修改html

<my-dire title="title1">这是一个面板,helloAngular</my-dire>
<my-dire title="title2">这是一个面板,helloAngular</my-dire>

增加动态属性

app.controller('appCtrl',function ($scope) {
    $scope.title1 = 'hello1';
    $scope.title2 = 'hello2'
});

修改指令

scope:{
    title:'='
}

1.6.3 "="与"@"区别 #

@单向绑定 html页面

控制器:<input type="text" ng-model="home">
<my-dire home="{{home}}"></my-dire>

控制器

app.controller('appCtrl',function ($scope) {
    $scope.home = 'home'
});
app.directive('myDire',function () {
    return {
        transclude:true,
        template:'指令内部<input type="text" ng-model="home">',
        scope:{
            home:'@'
        }
    }
});

=双向绑定 html页面

控制器:<input type="text" ng-model="hobby">
app.controller('appCtrl',function ($scope) {
     $scope.home = 'home';
+    $scope.hobby = 'hobby';
});
return {
+   template:'指令内部<input type="text" ng-model="hobby">',
    scope:{
         home:'@',
+        hobby:'='
    }
}

1.6.4 &绑定函数 #

html绑定方法

<my-dire home ="home(person)" name="{{name}}"></my-dire>

指令中调用函数

app.controller('appCtrl',function ($scope) {
    $scope.name = 'zfpx';
    $scope.home = function (who) {
        alert(who);
    }
});
app.directive('myDire',function () {
    return {
        template:'{{name}}<div ng-click="home({person:name})">谁的家</div>',
        scope:{
            home:'&',name:'@'
        }
    }
});

1.7 replace替换指令 #

增加replace:true替换原有指令

return {
    replace:true
}

1.8 compile函数 #

在link函数前执行,编译模板,返回的函数为link函数

<my-dire time="3"></my-dire>

指令中增加compile函数

return {
    transclude:true,
    template:'<div>Hello,zfpx {{title}}</div>',
    compile: function (element,attrs) {
        var tmpl = element.children();
        for(var i = 0; i < attrs.time-1;i++){
            element.append(tmpl.clone());
        }
        return function (scope,element,attrs) {
            scope.title = '123';
        }
    },
}

2.指令和指令间的交互 #

创建多个指令,依赖于girl指令

<girl love-money  ng-click="show()">Angular MM</girl>

创建指令公有部分

app.directive('girl',function () {
    return {
        controller: function ($scope) {
            var arr = [];
            this.add = function (attrs) {
                arr.push(attrs);
            };
            $scope.show = function () {
                alert(arr);
            }
        }
    }
});

创建指令间的依赖

app.directive('loveMoney',function () {
    return {
        require:'^girl',
        link: function (scope,element,attrs,girlCtrl) {
            girlCtrl.add('loveMoney');
        }
    }
});

3.opener指令demo #

增加css样式

.title{
    width: 100px;
    height: 30px;
    line-height: 30px;
    background: yellow;
}
.content{
    width: 100px;
    height: 100px;
    background: red;
}

增加指令

<opener title="标题1">这是内容1</opener>

增加引用模板

<div class="title" ng-click="show()">{{title}}</div>
<div class="content" ng-show="flag" ng-transclude></div>

增加指令

app.directive('opener',function () {
    return {
        templateUrl:'open.html',
        transclude:true,
        scope:{
            title:'@'
        },
        link:function(scope,element,attrs){
            scope.flag = true;
            scope.show = function () {
                scope.flag = !scope.flag;
            }
        }
    }
});

4.opener组 #

增加组

<group>
    <opener title="标题1">这是内容1</opener>
    <opener title="标题2">这是内容2</opener>
</group>

设置指令

app.directive('group', function () {
    return {
        controller: function ($scope) {
            var arr = [];
            this.add = function (scope) {
                arr.push(scope);
            }
            this.close = function (scope) {
                for(var i = 0; i<arr.length;i++){
                    if(arr[i]!=scope){
                        arr[i].flag = false;
                    }
                }
            }
        }
    }
});
app.directive('opener',function () {
    return {
        templateUrl:'open.html',
        transclude:true,
        require:'^group',
        scope:{
            title:'@'
        },
        link:function(scope,element,attrs,groupCtrl){
            scope.flag = false;
            scope.show = function () {
                scope.flag = !scope.flag;
                groupCtrl.close(scope);
            };
            groupCtrl.add(scope);
        }
    }
});