AngularJS Directive指令中require和controller属性

本文深入探讨AngularJS中子元素指令如何通过require属性与父元素指令通信,以及如何利用controller属性在父元素指令中定义可被子元素访问的方法。
  • require属性在创建子元素指令时添加,属性值描述与父元素指令通信时的方式。

    1. ^”符号表示向外层寻找指定名称的指令
    2. “?”符号表示即使没有找到,也不会出现异常

    require:"^?myDirective"表示向外层寻找名称为“myDirective”的指令,如果没有找到,也不出现异常,而这种向外层的方式,也包括本身,也就是说,可以在自身寻找其他名称的指令。

  • controller属性值是一个构造型函数,

    1. 创建父元素指令时添加,可以在该函数中添加多个方法或属性。
    2. 添加后,这些方法和属性都会被实例的对象所继承,而这个实例对象则是子元素指令中“link”函数的第4个参数。
    3. 也就是说,当在子元素指令中添加了require属性,并通过属性值指定父元素指令的名称。就可以通过子元素指令中“link”函数的第4个参数来访问父元素指令中controller属性添加的方法,因为这个参数是父元素指令的实例。
    4. 与在子元素指令中访问父元素的方法不同,在父元素中,添加构造函数时,函数中的参数就是子元素指令中的“scope”对象
    controller: function(){
        this.a = function(childDirective){
              //方法a的函数体
        }
    }
    

    在上述代码中,controller属性值对应一个构造函数,在函数中,this代表父元素指令本身,方法a是构造函数中的一个任意方法,在定义这个方法时,形参childDirective就是子元素指令中的scope对象,通过这种方式,在父元素中,可以很轻易访问到子元素指令中的scope对象。

使用require和controller属性的示例

  1. 功能描述
    自定义两个名称分别为“tsParent”和“tsChild”的指令,并在这两个指令中分别添加名为“ptip”和“ctip”的属性,并通过双大括号的方式将属性值显示在指令元素中。此外,在“tsParent”指令元素中再添加一个“换位”按钮,单击该按钮后,两个指令中绑定的属性值内容进行互换。
  2. 实现代码
<!DOCTYPE html>
<html ng-app="a8_8">
<head>
    <title>一个使用require和controller属性的示例</title>
    <script src="/node_modules/angular/angular.min.js"></script>
    <style type="text/css">
        .frame {
            padding: 2px 8px;
            margin: 0px;
            font-size: 12px;
            width: 320px;
            background-color: #eee;
        }

        .tip {
            font-size: 9px;
            color: #666;
            margin: 3px 0px;
            padding: 5px 0px;
        }
    </style>
</head>
<body>
    <div class="frame">
        <ts-parent>
            <div class="tip">{{ptip}}</div>
            <ts-child>
                <div class="tip">{{ctip}}</div>
            </ts-child>
            <button ng-click="click()">换位</button>
        </ts-parent>
    </div>
    <script type="text/javascript">
        var app = angular.module('a8_8', [])
        .directive('tsParent', function () {
            return {
                restrict: 'EAC',
                controller: function ($scope, $compile, $http) {
                    this.addChild = function (c) {
                        $scope.ptip = "今天天气不错!";
                        $scope.click = function () {
                            $scope.tmp = $scope.ptip;
                            $scope.ptip = c.ctip;
                            c.ctip = $scope.tmp;
                        }
                    }
                }
            };
        })
        .directive('tsChild', function () {
            return {
                restrict: 'EAC',
                require: '^?tsParent',
                link: function (scope, iEle, iAttrs, ctrl) {
                    scope.ctip = '气温正好18摄氏度。';
                    ctrl.addChild(scope);
                }
            };
        });
    </script>
</body>
</html>
  1. 源码分析
    1. 自定义名称为tsChild指令时添加“require”属性,并将它的属性值设置为^?tsParent,向外寻找名称为“tsParent”的指令;
    2. 在添加的“link”函数中,通过scope对象向所辖的作用域中添加名为“ctip”的属性,便于在指令元素中通过双大括号绑定显示。
    3. 在自定义名称为“tsChild”指令时,通过“link”函数中的第4个参数访问“tsParent”指令中“controller”函数中定义的方法,并将指令元素所在的scope对象作为实参传递给名称为“tsParent”的指令,从而实现在子级指令中访问上级指令中方法的功能。
    4. 在“tsParent”的指令中添加“controller”函数,并在函数中构建一个名称为“addChild”的方法,用于子级指令的调用,并通过在调用过程中该方法传来的实参,获取到子级指令中的scope对象,再将本作用域中的“ptip”属性与获取的子作用域中的“ctip”属性的值进行互换,从而实现在父级指令中访问子级指令中属性的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值