$scope
传递的controller
与$scope
传递的directive
之间有何区别和关系?
你会如何设置它们?
答案 0 :(得分:1)
这是对$scope
中传递的controller
与$scope
中传递的directive
之间差异和关系的简要说明。 :强>
正如您在下面的基本角度设置中所见,$scope
传递给Angular Controller
和Angular Directive
。但是有哪些差异,这些$scope
如何相互关联和相互作用?
基本角度设置
Angular App:
angular.module('app', []);
角度控制器:
angular.module('app').controller('mainCtrl', function($scope) {
$scope.user = {
name: 'Luke Skywalker',
address: {
street: 'PO Box 123',
city: 'Secret Rebel Base',
planet: 'Yavin 4'
},
friends: [
'Han',
'Leia',
'Chewbacca'
]
}
});
Angular Directive:
angular.module('app').directive('userInfoCard', function() {
return {
templateUrl: "userInfoCard.html",
restrict: "E",
controller: function($scope) {
$scope.knightMe = function(user) {
user.rank = "knight";
}
}
}
});
您可以通过3种方式设置directive scope
与包含controller scope
之间的关系:
默认情况下,directive
到 分享 范围包含controller
。该图说明了这种关系。
指令范围 - 共享
您可以看到紫色的父$scope
,我们可以在父User object
上看到我们的Controller
。共享$ scope的指令完全存在于父controller's $scope
中,并且它可以访问父controller $scope
上的每个对象。
如果指令必须修改或添加到$ scope的项目,它将属于parent controller's $scope
而不是directive
。如果您必须在controller
和directive
添加一行以注销$scope
(console.log($scope);
,则可以轻松查看此内容。您会注意到 ChildScopes 的 $ id 将是相同的。
共享范围是处理$scope
中directives
的最简单方法。
指令继承范围
下图说明了directive
继承的$scope
:
图1
我们再一次在控制器$ scope中创建了一个用户对象,但指令设置为继承$ scope。
当我们在directive $scope
中创建新项目时,它将变为内部数据,并且对父$scope
不可见。换句话说,该项目将位于directive $scope
而不是父级$scope
上。
见下面的图表:
图2
您可能希望这样做有几个原因,最常见的是封装 directive
内的数据。
要创建包含继承$scope
的指令,请在指令中添加scope
property
,并将其设置为true
(将其设置为false
将被共享$scope
- 这在任何情况下都是默认的。)
请参阅下面的directive
代码:
Angular Directive:
angular.module('app').directive('userInfoCard', function() {
return {
templateUrl: "userInfoCard.html",
restrict: "E",
scope: true,
controller: function($scope) {
$scope.knightMe = function(user) {
user.rank = "knight";
}
}
}
});
当您通过控制台注销时,您会注意到2个ChildScope对象。但是这次 $ id 对于每个$scope
对象都不同。
需要注意的一件事:directive
ChildScope对象有一个名为 $ parent 的属性。这与controller
ChildScope对象具有相同的 $ id 。因此,包含controller $scope
已设置为directive $scope
的 $ parent 。您还会注意到用户对象在父 $scope
中可见。这是真正的JavaScript 继承。
注意:您会注意到指令ChildScope对象具有原型(_proto_
)。当您查看原型时,您可以看到这也是该指令的同一范围对象,从而实现了这种真正的继承。
阅读:
https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
http://javascript.info/tutorial/inheritance
这里的主要区别不在于子范围可以在父范围上看到的内容,而是在子范围创建新数据时会发生什么。此数据在子范围内部,对父范围不可见。
隔离范围
下图说明了这种情况:
我们再次拥有包含用户对象的父controller
$scope
。与继承 $scope
一样,directive
$scope
中创建的数据将内部且不可见到controller
$scope
。
但是我们遇到directive $scope
无法查看controller $scope
上的数据的问题。我们通常希望查看controller $scope
的某些数据元素。
要解决此问题,您可以逐个对象地在隔离的$scope
和父$scope
之间创建特殊绑定。这样,孤立的$scope
无法看到父$scope
上的所有内容,但它可以看到您可见的特定项目。
为此,您可以将范围属性中的 true 更改为对象{} 。
如果您必须将此日志记录到控制台,您会再次看到每个ChildScope对象都有自己唯一的 $ id 。您还会注意到子范围(directive
)仍然具有 $ parent 对象,该对象是父范围(controller
),但这次没有父范围链接到原型。
要使controller
范围内directive
的用户对象可见,您可以将属性添加到" user&的指令范围对象中#34;,并将其值设置为" =",告诉范围期望将对象传递给它,其值为" user"。
以下代码演示了这一点:
angular.module('app').directive('userInfoCard', function() {
return {
templateUrl: "userInfoCard.html",
restrict: "E",
scope: {
user: '='
},
controller: function($scope) {
$scope.collapsed = ($scope.initialCollapsed === 'true');
$scope.knightMe = function(user) {
user.rank = "knight";
}
$scope.collapse = function() {
$scope.collapsed = !$scope.collapsed;
}
}
}
});
这是设置directive
范围与包含controller
范围之间关系的3种方法。
特别感谢Joe Eames。 https://github.com/joeeames