angularjs中的作用域与原生js中的函数嵌套原理一致,都是存在作用域的继承。若在子控制器(同样包括在指令中的link或是controllerding中定义变量,此时指令中必须未使用scope独立作用域)未定义相关变量,那么它会向父控制器一层层查找,直到找到位为止。
若在自定义指令中的link、controller与该指令的父控制器定义了同名变量,那它的作用域是如何的呢,以及指令中的独立作用域scope会对改变量产生怎样的影响,以例说明:
HTML:
<div ng-controller="test"> <div>模块下控制器:{{param}}</div> <dir-scope></dir-scope></div>
js:
var myApp=angular.module("myApp",[]); myApp.controller("test",["$scope",function($scope){ $scope.param="moudelController-param"; }]); myApp.directive("dirScope",function(){ return{ restrict:"AE", scope:{ param:"@" }, template:"<div>{{param}}</div>", replace:true, controller:function($scope,$element,$attrs){ $scope.param="dirController-param"; }, link:function(scope,ele,attrs){ console.log("link param:" + scope.param); ele.bind("click",function(){ scope.param="link-param"; scope.$apply(); console.log("link click param:" + scope.param); }) } } })
(一)使用独立作用域scope的情况
初次运行结果:
页面:
控制台:
在页面中,模块下控制器与指令中显示的不同,说明模块下控制器中的param与指令中的param互为独立的(可以理解为两个不同的变量,因为当指令中使用独立作用域scope时,若在指令中未定义该变量则不会向父控制器查找同名变量)。然而在控制台输出了在指令中link阶段param的值为 dirController-param,说明指令中的link、controller使用的为同一变量,当点击页面中的“dirController-param”会触发在指令link阶段定义的click事件,触发结果也说明了模块下控制器中的变量与指令中的同名变量互为独立的,已下为触发结果:
页面:
控制台:
(二)未使用使用独立作用域scope的情况
将以上代码中的scope:{param:"@"}注释掉,结果如下:
页面:
控制台:
程序是按照控制器->指令中的link->指令中的controller 的顺序来运行的,在指令的controller中对param赋的值覆盖了模块下的控制器对param赋的值,在指令中的link阶段同样输出的是“dirController-param”,说明模块下的controller与指令的controller、link中定义的同名变量为同一变量。点击页面中的“dirController-param”触发的变化同样说明了这个问题,一下为点击“dirController-param”后的界面:
页面:
控制台: