angular自定义指令取得控制器数据的方法

为什么

  • 一般我们自定义指令,是为了封装一整段DOM结构或作操作DOM的方法,涉及到编译新DOM树。所以必须获得编译前DOM结构作用域的数据才能对其作出改变。但是我们的自定义指令的作用域并不是DOM结构的作用域,所以必须通过一些方法来获得DOM作用域。接下来是方法总结。

    通过自定义指令的scope属性

  • 数据按类型可以分为三类:字面量、变量、方法。在directive中的scope属性提供了3种操作符来分别获得这三种数据。获取的流程相同,主要是不同的操作符。
  • 字面量的获取
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <div ng-controller="myCtrl">
    myCtrl:<input type="text" ng-model="name">
    my-dir:<my-dir name="{{name}}"></my-dir>
    </div>
    <script>
    var myApp=angular.module('myApp',[]);
    myApp.controller('myCtrl',['$scope',function ($scope) {
    $scope.name='KOBE';
    }])
    myApp.directive('myDir',function () {
    return {
    template:'<input type="text" ng-model="name1">',
    scope:{
    name1:'@name'
    }
    }
    })
  1. 首先在编译前的DOM结构中

    1
    2
    3
    4
    <div ng-controller="myCtrl">
    myCtrl:<input type="text" ng-model="name">
    my-dir:<my-dir name="{{name}}"></my-dir>
    </div>

    由于my-dir与input同属myCrl控制器,所以my-dir中的name可以取得控制器中的,也就是input标签中ng-model所绑定的name。

  2. name保存在自定义指令scope属性中的@name中。

    1
    2
    3
    4
    5
    6
    7
    8
    myApp.directive('myDir',function () {
    return {
    template:'<input type="text" ng-model="name1">',
    scope:{
    name1:'@name'
    }
    }
    })

    其中@符号代表该数据是字面量。将其值赋给name1.(这里如果name:’@name’可以简写为name:’@’.)

  3. 将name1赋给模板中的ng-model属性。

    1
    template:'<input type="text" ng-model="name1">',

这样编译后的DOM结构中ng-model就得到编译前input中保存的name。

  • 变量的获取

字面量与变量的区别

1
2
3
4
<!--字面量-->
my-dir:<my-dir name="{{name}}"></my-dir>
<!--变量-->
my-dir:<my-dir name="name"></my-dir>

这里my-dir中name获得的是控制器作用域中的$scope.name变量而不是$scope.name所对应的值。
与前面字面量数据的获得唯一的区别在于第二步将’@’符号改为’=’,即

1
2
3
4
5
6
7
8
myApp.directive('myDir',function () {
return {
template:'<input type="text" ng-model="name1">',
scope:{
name1:'=name'
}
}
})

-方法的获取
方法的获取符号为”&”。有一点坑在于如果方法需要传参,需要用对象的方式来赋值

1
2
3
4
5
6
7
8
9
//编译前的模板
my-dir:<my-dir name="nameDir" greet="greetCtrl(d)"></my-dir>
//directive中的参数
template:'<input type="text" ng-model="nameDir"> <button ng-click="greetDir({d:nameDir})">点我</button>',
scope:{
nameDir:'=name',
greetDir:'&greet'
},

通过ng-transclude获取数据

  • 在指令属性中设置transclude:true,