angularJs指令

指令是angularJs里非常常用和重要的一部分。
指令是什么:简单点说,指令就是一些附加在html元素上的自定义标记(例如:元素、属性、css类等),它告诉AngularJS的HTML编译器 ($compile) 在元素上附加某些指定的行为,甚至操作DOM、改变DOM元素,以及它的各级子节点。
angular 有一些内置的指令:ngBind,ngModel等,如<input ng-model="name">

指令创建

通常指令创建在独立的js文件作为一个模块,可以复用
页面

<body>
    <hello></hello>
    <div hello></div>
    <div class="hello"></div>
    <!--directive:hello -->
    <div></div>
</body>

js文件

    var snDirective = angular.module("snDirective",['ngCommon']);
    /**
     * 简单的例子
     */
    snDirective.directive("hello", function(){
        return {
            restrict:'AEMC',
            replace:true,
            template:"<div> hello world</div>"
        }
    })

    /**
     * 图片加载失败时替换成指定图片
     */
    snDirective.directive("errSrc", function() {
        return {
            link: function(scope, element, attrs) {
                element.bind("error", function() {
                    //src属性 != errSrc属性。则src属性值设置为errSrc属性值
                    if (attrs.src != attrs["errSrc"]) {
                        attrs.$set("src", attrs["errSrc"]);
                    }
                });
            }
        }
    });

    /**
     * snDialog:弹出层窗口
     */
    snDirective.directive("snDialog", function () {
        return {
            restrict: "AE",
            replace: true,
            transclude: true,
            scope: {},
            templateUrl: jsPath + "directive/sn-dialog.html?v=" + window.VERSION,
            link : function(scope, element, attr) {

            }
        };
    });

指令修改dom通常是在link函数中。link函数可以给指令元素绑定一些事件。如示例代码errSrc。指令里的link函数三、四个参数,element是元素,这里是指令本身,attrs是指令上的属性
restrict:匹配模式,即指令使用的方式。有A属性,E元素,M注释,C class。
什么情况下该用元素名,什么情况下该用属性名? 当创建一个含有自己模板的组件的时候,建议使用元素名,常见情况是,当你想为你的模板创建一个DSL(特定领域语言)的时候。如果仅仅想为已有的元素添加功能,建议使用属性名.
scope:{}:创建指令的独立作用域。如果页面多个相同指令,指令的template 如<input type="text" ng-model="userName">{{userName}}</input>。修改其中一个指令的输入框,都会同时作用在其他几个相同的指令上。如果需要指令间互不影响则需要指令上添加scope:{} 配置项。
详细参考angularJs中文网指令文档。

transclude:指令内部是否可嵌套。即页面上指令内部与指令无关的html代码块可以嵌套到指令模板里的<div ng-transclude></div>这里。
replace:将视图模板替换到自定义指令名称位置时,是否替换掉自定义指令名称,默认为false不替换。

指令与控制器

同一个controller里调用指令。

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

myModule.controller("myCtrl",["$scope", function($scope){
    $scope.loadData = function(){
        console.log("加载数据。。。。");
    }
}])

myModule.directive("loader",function(){
    return {
        restrict: "AE",
        link: function(scope,element,attr){
            element.bind("mouseenter",function(){
                scope.loadData();//因为指令在controller包含里,所以作用域一直,可以调用?
                or
                scope.$apply("loadData()");
            })
        }
    }
})

<div ng-controller="myCtrl">
    <loader>滑动加载</loader>
</div>

不同的控制器调用同一个指令。可以在指令上定义一个属性, 实现指令复用

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

myModule.controller("myCtrl",["$scope", function($scope){
    $scope.loadData = function(){
        console.log("加载数据。。。。");
    }
}])

myModule.controller("myCtrl2",["$scope", function($scope){
    $scope.loadData2 = function(){
        console.log("加载数据。。。。222");
    }
}])

myModule.directive("loader",function(){
    return {
        restrict: "AE",
        link: function(scope,element,attr){
            element.bind("mouseenter",function(){

                scope.$apply(attr.howtoload());//howtoload不能驼峰
            })
        }
    }
})


<div ng-controller="myCtrl">
    <loader howToLoad="loadData()">滑动加载</loader>
</div>
<div ng-controller="myCtrl2">
    <loader howToLoad="loadData2()">滑动加载</loader>
</div>
指令与指令交互

指令里的controller用于为指令暴露一组public方法,供外部指令调用。这是指令里controller的作用

var module = angular.module("myModule",[]);
module.directive("superman",function(){
    return {
        scope:{},
        restrict: "AE",
        controller: function(){//
            $scope.abilities = [];
            this.addStrength = function(){
                $scope.abilities.push("strength");
            }
            this.addSpeed = function(){
                $scope.abilities.push("speed");
            }
        }
        link: function(scope,element,attr){
            element.addClass("btn btn-primary");
            element.bind("mouseenter",function(){
                console.log(scope.abilities);
            })
        }
    }
})

module.directive("strength",function(){
    return {
        require: "^superman",
        link: function(scope,element,attrs, supermanCtrl){
            supermanCtrl.addStrength();
        }
    }
})

module.directive("speed",function(){
    return {
        require: "^superman",
        link: function(scope,element,attrs, supermanCtrl){
            supermanCtrl.addSpeed();
        }
    }
})

<div class="row">
    <div class="col-md-3">
        <superman strength> 超人。。。力量</superman>
    </div>
</div>
<div class="row">
    <div class="col-md-3">
        <superman strength speed> 超人。。。力量和速度</superman>
    </div>
</div>
scope的绑定策略

@绑定
把当前的属性作为字符串传递。你还可以绑定来自外层的scope的值,在属性值中插入{{}}即可。

html代码,其中flavor是指令自定义属性,由于@绑定的字符串,所以flavor="{{ctrlFlavor}}"里的ctrlFlavor只能是字符串,不能是对象

<div ng-controller="myCtrl">  
    <drink flavor="{{ctrlFlavor}}"></drink>  
</div>

js代码

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

myModule.controller('myCtrl',['$scope',function($scope){  
    $scope.ctrlFlavor="香菇";  
}])  
myModule.directive("drink",function(){  
   return{  
        restrict:'AE',  
        scope:{  
           flavor:'@'  
        },  
        template:"<div>{{zk}}</div>"  
        //link: function(scope,element,attrs){
        //     scope.flavor = attrs.flavor
        //}
   }  
})

=绑定
与父scope中的属性进行双向绑定
html代码

<div ng-controller="myCtrl">  
    Ctrl:  
    <br>  
    <input type="text" ng-model="ctrlFlavor">  
    <br>  
    Directive:  
    <br>  
    <drink flavor="ctrlFlavor"></drink>  
</div> 

js代码

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

myModule.controller('myCtrl', ['$scope', function ($scope) {  
    $scope.ctrlFlavor = "香菇";  
}]);  

myModule.directive("drink", function () {  
    return {  
       restrict: 'AE',  
       scope: { 
           flavor: '=' 
       },  
       template: '<input type="text" ng-model="flavor">'  
    }  
});

注意
指令scope:{}里的flavor可以不和html里的flavor=”ctrlFlavor”的flavor相等。可以自命名为myflavor。
这时候就要scope:{myflavor: '=flavor'}同时template里的ng-model="myflavor".

&绑定
传递来自父scope中的函数、稍后调用

html代码

<div ng-controller="MyCtrl">  
    <greeting greet="sayHello(name)"></greeting>
    <greeting greet="sayHello(name)"></greeting>
    <greeting greet="sayHello(name)"></greeting>
</div>

js代码

var myModule=angular.module("MyModule",[]);  
myModule.controller('MyCtrl', ['$scope', function($scope){  
    $scope.sayHello=function(name){  
        alert("Hello "+name);  
    }  
}])  
myModule.directive("greeting", function() {  
    return {  
        restrict:'AE',  
        scope:{  
            greet:'&'  
        },  
        template:'<input type="text" ng-model="userName" /><br/>'  
        + '<button class="btn btn-default" ng-click="greet({name:userName})">'  
        + 'Greeting</button><br/>'  
    }  
});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值