以下是两个指令:
aDirective,创建一个新的孤立范围;
bDirective不会创建新范围。
app.directive('aDirective', [function () {
return {
restrict: 'A',
scope: {}, // isolated scope
link: function (scope, iElement, iAttrs) {
}
};
}])
.directive('bDirective', [function () {
return {
restrict: 'A',
scope: false,
link: function (scope, iElement, iAttrs) {
}
};
}]);
现在将这两个指令应用于一个DOM元素:
<div ng-app="myApp">
<div ng-controller="myController">
<input id="targetElement" type="text" a-directive b-directive />
</div>
</div>
我得到的结果是它检索目标元素的范围。
//true
angular.element("#targetElement").isolateScope().$parent
=== angular.element("#targetElement").scope()
所以我的问题是为什么单个DOM元素同时拥有两个范围(非隔离范围和隔离范围)。
答案 0 :(得分:1)
因为在第一个指令中你有一个独立的范围,这意味着它有自己的范围,但是如果检查它的父对象,你仍然会在那里找到父控制器。
让我们说如果我的控制器如下所示
app.controller('myController', function($scope) {
$scope.obj='abc'
})
我只有一个名为 obj
的属性案例1:隔离范围 现在,如果我创建像你的指令
app.directive('aDirective', [function () {
return {
restrict: 'A',
scope: {}, // isolated scope
controller: function ($scope) {
console.dir($scope)
},
link: function (scope, iElement, iAttrs) {
console.log('From aDirective')
console.dir(scope)
}
};
}])
此处范围是隔离的,这意味着该指令不会共享父控制器的任何属性。但是如果想拥有在控制器范围内声明的属性,可以访问范围变量的父属性。
在上面的图像中,您可以看到顶层没有obj属性,但您可以在对象的$ parent属性中看到它,实际上是父控制器范围,如下所示
案例2:共享范围
现在在我的范围未被隔离且其实际共享的指令中,如下所示
app.directive('bDirective', [function () {
return {
restrict: 'A',
scope: false,
controller: function ($scope) {
console.dir($scope)
},
link: function (scope, iElement, iAttrs) {
console.log('From bDirective')
console.dir(scope)
}
};
}]);
这里,当我将探索范围对象的对象层次结构时,我将仅在顶部找到obj属性,不需要$ parent属性来获取在父控制器中声明的属性,因为您正在共享范围
现在回到你的问题
//true
angular.element("#targetElement").isolateScope().$parent
=== angular.element("#targetElement").scope()
上面的代码将始终返回true,因为两者都使用相同的控制器,并且您将隔离范围的$ parent对象与共享范围进行比较,共享范围只是控制器的范围。
如果你comapare
angular.element("#targetElement").isolateScope()
=== angular.element("#targetElement").scope()
你会得到假的。
同样在最大值时,使用指令时只能有两个范围,即父范围和指令范围。
由于您创建了一个具有隔离范围和其他具有共享范围的范围,因此具有最多两个范围的规则正在实现,这就是它工作的原因。
如果您的指令具有如下所示的范围,则它将无效并且会给您例外(如果两个指令都装饰在一个元素上)
Directive1-> {} and Directive2 -> {}
Directive1-> {} and Directive2 -> true
Directive1-> true and Directive2 -> {}
因此,如果范围如下所示(如果两个指令都在一个元素上修饰),则指令的唯一方法将起作用
Directive1-> {} and Directive2 -> false
Directive1-> false and Directive2 -> {}
Directive1-> false and Directive2 -> false