传递给控制器的$ scope和传递给指令的$ scope之间的区别和关系 [英] The difference and relationship between the $scope passed in a controller, and the $scope passed in a directive
问题描述
controller
中传递的$scope
与directive
中传递的$scope
有什么区别和关系?
What is the difference and relationship between the $scope
passed in a controller
, and the $scope
passed in a directive
?
您将如何设置它们?
推荐答案
这是对controller
中传递的$scope
与传递的$scope
之间的区别和关系的简要说明.在directive
中是:
This is a brief explanation of what is the difference and relationship between the $scope
passed in a controller
, and the $scope
passed in a directive
is:
从下面的基本Angular设置中可以看到,$scope
既传递给Angular Controller
,又传递给Angular Directive
.但是有什么区别,这些$scope
如何相互关联和交互?
As you can see form the basic Angular setup below, $scope
is passed to both the Angular Controller
and to the Angular Directive
. But what are the differences, and how do these $scope
s relate and interact with each other?
基本角度设置
Angular应用:
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.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
之间的关系:
There are 3 ways you can set up the relationship between the directive scope
and the containing controller scope
:
默认设置是directive
与包含controller
的范围 共享 .此图说明了这种关系.
The default is for the directive
to share the scope with the containing controller
. This diagram illustrates this relationship.
指令范围-共享
您可以看到紫色的父级$scope
,我们可以看到在父级Controller
上创建的User object
.具有共享$ scope的指令完全位于父级controller's $scope
中,并且可以访问父级controller $scope
上的每个对象.
You can see the parent $scope
in purple, and we can see our User object
created on the Parent Controller
. The directive with the shared $scope lives entirely in the parent controller's $scope
, and it has access to every object on the parent's controller $scope
.
如果指令必须修改$ scope或将项目添加到$ scope,它将属于parent controller's $scope
而不是directive
.如果您必须在controller
和directive
上添加一行以注销$scope
(console.log($scope);
,则可以轻松地看到这一点.您会注意到,两个 ChildScopes 的 $ id 都是相同的.
If the directive had to modify or add items to the $scope, it would belong to the parent controller's $scope
and not the directive
. You can easily see this if you had to add a line to the controller
and the directive
to log out the $scope
(console.log($scope);
). You will note the $id of both ChildScopes would be the same.
共享范围是处理directives
中$scope
的最简单方法.
Shared Scope is the simplest way to deal with $scope
in directives
.
指令继承范围
下图说明了directive
继承的$scope
:
图1
我们再次在控制器$ scope中创建了一个用户对象,但将指令设置为继承了$ scope.
We once again have a user object created in the controller $scope, but with the directive set up to have inherited $scope.
当我们在directive $scope
中创建新项目时,它将变为内部数据,并且对父级$scope
不可见.换句话说,该项目将驻留在directive $scope
上,而不是在父$scope
上.
When we create a new item in the directive $scope
, it will become Internal Data, and not visible to the parent $scope
. In other words that item will live on the directive $scope
and not on the parent $scope
.
请参见下面的图2 :
图2
您要这样做的原因有很多,最常见的是将directive
中的数据封装.
There are several reasons why you would want to do this, the most common would be to encapsulate the data inside the directive
.
要创建具有继承的$scope
的指令,请在指令中添加scope
property
并将其设置为true
(将其设置为false
将被共享$scope
-这是在任何情况下都是默认值.
To create a directive with inherited $scope
, you add a scope
property
to the directive, and set it to true
(setting it to false
would be shared $scope
- which is the default in any case).
请参见下面的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对象.但是这次,每个$scope
对象的 $ id 不同.
When you log this out via the console, you will notice 2 ChildScope objects as before. But this time the $id is different for each $scope
object.
需要注意的一点:directive
ChildScope对象具有一个名为 $ parent 的属性.它与controller
ChildScope对象具有相同的 $ id .因此,包含的controller $scope
已被设置为directive $scope
的 $ parent .您还将注意到用户对象在父级 $scope
中可见.这是真正的JavaScript 继承.
One thing to note: the directive
ChildScope object has a property called $parent. This has the same $id as the controller
ChildScope object. So the containing controller $scope
has been set as the $parent of the directive $scope
. You will also note the user object is visible in the parent $scope
. This is true JavaScript inheritance.
注意:您将注意到指令ChildScope对象具有原型(_proto_
).当您查看原型时,您会发现这也是该指令的同一作用域对象,从而实现了真正的继承.
Note: You will notice that the directive ChildScope object has a prototype (_proto_
). When you look at the prototype, you can see that this is also that same scope object of the directive, making this true inheritance.
阅读:
https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
http://javascript.info/tutorial/inheritance
此处的主要区别不是子范围在父范围上可以看到的内容,而是子范围创建新数据时发生的情况.此数据在子作用域内部,而对父作用域不可见.
隔离范围
下图说明了这种情况:
再一次,我们有一个包含 user 对象的父controller
$scope
.与继承的 $scope
一样,在directive
$scope
中创建的数据将对$scope
.
Once again we have a parent controller
$scope
that contains a user object. And as with inherited $scope
, the data created in the directive
$scope
will be internal and not visible to the controller
$scope
.
但是我们遇到的问题是directive $scope
无法看到controller $scope
上的数据.通常,我们希望看到controller $scope
的某些数据元素.
But we have the issue of the directive $scope
not being able to see the data on the controller $scope
. Often we would want to see certain data elements of the controller $scope
.
为解决这个问题,您可以在逐个对象的基础上,在隔离的$scope
和父级$scope
之间创建特殊的绑定.这样,孤立的$scope
不能看到父级$scope
上的所有内容,但是可以看到您看到的特定项目.
To solve this you can create a special binding between the isolated $scope
and the parent $scope
on an object by object basis. This way the isolated $scope
cannot see everything on the parent $scope
, but it can see specific items you make visible.
为此,请将 scope 属性上的 true 更改为对象{} .
To do this, you change the true on the scope property to an object {}.
如果必须将此登录到控制台,您将再次看到每个ChildScope对象都有其自己的唯一 $ id .您还将注意到,子作用域(directive
)仍然具有 $ parent 对象,该对象是父作用域(controller
),但是这次没有父作用域链接到原型.
If you had to log this to the console, you would see once again that each ChildScope objects has its own unique $id. You will also note that the child scope (directive
) still has a $parent object that is the parent scope (controller
), but this time there is no parent scope linked to the prototype.
要使controller
的 user 对象在directive
的范围内可见,可以向"user"的指令范围对象添加一个属性,并将其值设置为"=",告诉作用域期望使用"user"的值将对象传递给该对象.
To make the user object of the controller
visible to the scope of the directive
, you can add a property to the directive scope object of "user", and set its value to "=", telling the scope to expect an object to be passed to it with the value of "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
范围之间建立关系的三种方法.
And that is the 3 ways to set up the relationship between the directive
scope and the containing controller
scope.
特别感谢Joe Eames. https://github.com/joeeames
A special thanks to Joe Eames. https://github.com/joeeames
这篇关于传递给控制器的$ scope和传递给指令的$ scope之间的区别和关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!