指令内部通过scope:true false {} 三种来控制作用域。
先来介绍scope:true的情况:
<div ng-controller="firstCtrl"> {{myProperty}} <input ng-model="myProperty" /><br /> <div my-directive></div> </div> <script> angular.module('testApp', []) .controller('firstCtrl', ['$scope', function ($scope) { $scope.myProperty = 'hello word'; }]) .directive('myDirective', function () { return { restrict: 'A', scope: true, template: '<div>内部{{myProperty}}<input ng-model="myProperty">' } }) </script>
用这种方式控制的作用域表示为继承并且隔离,也就是说,指令内部是继承了firstCtrl的myProperty变量,通过修改父控制器变量值的时候,指令内部也会发生变化。
但修改指令内部的变量时,不会影响到父控制器的变量。需要注意的是,当修改了一次指令内部值的时候,如果再次修改父控制的变量,这时指令内部的变量不再会跟随父控制器发生变化,
相当于在指令内部创建了一个自己的变量。
scope: false 时,表示继承但不隔离,也就是说父控制器的变量和指令内部中的变量始终保持一致。
scope:{}时,表示隔离且不继承,但是,如果需要使用父作用域传入的参数,可以使用:@ = & 三种来进行绑定,@表示进行单向传入,参数会以一个字符串的形式传入到指令中。
这种方式需要注意的是,如果传递对象时,对象也会变成字符串,这就需要用=号来进行传递,=表示为双向传入,也就是说传入的变量和父作用域始终保持一致。
&一般当传入方法时,用到这个地址符。(后续会有详细的说明,并填上代码)
transclude:一般在嵌套指令时会用到这个属性。一般来说,指令会把内容替换为内部的模板,但有一种情况就是当指令的元素下面还有其他的html元素时,这时,其他的html元素会被替换,这显然不是想要的结果。
所以这时候就需要设置transclude这个属性了。
<div ng-controller="bodyCtrl"> <div father-directive><span>{{str}}</span></div> </div> <script> angular.module('testApp', []) .controller('bodyCtrl', ['$scope', function ($scope) { $scope.str = 'ctrl'; }]) .directive('fatherDirective', function () { return { restrict: 'A', transclude: true, template: ' <div>father <div ng-transclude></div></div>' } }) .directive('sonDirective', function () { return { restrict: 'A', template: '<div>son</div>' } })
上面的代码中可以看到,在指令的内部又包含了一个bodyCtrl的str变量,这时,如果没有transclude:true的话,这个str会直接被替换,而不显示,
所以设置transclude:true之后,在指令内部模板中,设置一个元素如div并设置一个ng-transclude属性,这样就把这些外部元素都放到了这个div下。