javascript 为什么我的 AngularJS 指令共享范围?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19774918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are my AngularJS directives sharing scope?
提问by nickponline
I've tried to make a simple directive which displays a name and allows it to be change. When I put multiple directive on the name page they all seem to share the name attribute. What am I doing wrong?
我试图制作一个简单的指令,显示名称并允许更改。当我在名称页面上放置多个指令时,它们似乎都共享名称属性。我究竟做错了什么?
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset=utf-8 />
<title></title>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular-resource.min.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular-animate.min.js"></script>
<script>
var app = angular.module('app', []);
app.directive('person', function () {
function link ($scope, elem, attrs, ctrl) {
$scope.name = "OLD"
$scope.setName = function() {
$scope.name = 'NEW';
}
}
return {
restrict: 'E',
replace: true,
template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>",
link : link,
}
});
app.controller('MainCtrl', function ($scope) { });
</script>
</head>
<body ng-controller='MainCtrl'>
<person></person><br>
<person></person><br>
<person></person><br>
<person></person><br>
</body>
</html>
回答by Stokes Player
As mentioned in previous answers, the default behavior of AngularJS directives is to share the scope that they are included in. This behavior is changed via the scope
parameter in the directive definition object.
正如前面的回答中提到的,AngularJS 指令的默认行为是共享它们所包含的范围。这个行为是通过scope
指令定义对象中的参数来改变的。
You can view the documentation for the scope argument in this section of the AngularJS documents: http://docs.angularjs.org/api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
您可以在 AngularJS 文档的这一部分查看范围参数的文档:http: //docs.angularjs.org/api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
This argument has three options:
这个论点有三个选项:
scope: false
- the default behavior of sharing the scope the directive is included inscope: true
- create a new scope for the directive that acts like other child scopes and prototypically inherits from its parent scope- See Example 1
scope: {}
- create an isolated scope that does not prototypically inherit from its parent scope- See Example 2
scope: false
- 共享指令所包含的范围的默认行为scope: true
- 为指令创建一个新的作用域,它的作用类似于其他子作用域,并且原型继承自其父作用域- 参见示例 1
scope: {}
- 创建一个独立的范围,该范围不典型地从其父范围继承- 参见示例 2
As you can see with the JSBin examples, both options 2 and 3 will work for your example. The difference is whether you want your new scopes isolated or not.
正如您在 JSBin 示例中看到的那样,选项 2 和选项 3 都适用于您的示例。不同之处在于您是否希望隔离您的新范围。
The directives section of the AngularJS guide has a good section on why isolated scope can help create better reusable modules with directives: AngularJS Guide: Isolating the Scope of a Directive
AngularJS 指南的指令部分有一个很好的部分,说明为什么隔离范围可以帮助创建更好的可重用模块与指令: AngularJS 指南:隔离指令的范围
回答by Nicolas ABRIC
By default if you don't isolate the scope of a directive you will share the "outside" scope with all instances of your person directive. With your current implementation you'd need to create a different controller each time in order to re-use such a directive.
默认情况下,如果您不隔离指令的范围,您将与您的 person 指令的所有实例共享“外部”范围。对于您当前的实现,您每次都需要创建一个不同的控制器才能重用这样的指令。
BUT there is a solution to this flaw and it s called isolate scope. To do this, you can use a directive's scope option like so :
但是这个缺陷有一个解决方案,它被称为隔离范围。为此,您可以使用指令的范围选项,如下所示:
return {
restrict: 'E',
replace: true,
scope : {}, // this is where the magic happens
template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>",
link : link,
}
You have a complete example and explenation over heresection Isolating the Scope of a Directive
你有一个完整的例子,explenation在这里部分隔离一个指令范围
回答by Stephane Rolland
By default, directives share the same scope. But if needed, you can use isolated scopefor your directives: use scope: {}
as field in your directive definition.
默认情况下,指令共享相同的范围。但如果需要,您可以为指令使用隔离范围:scope: {}
在指令定义中用作字段。
app.directive('person', function () {
function link ($scope, elem, attrs, ctrl) {
$scope.name = "OLD"
$scope.setName = function() {
$scope.name = 'NEW';
}
}
return {
restrict: 'E',
scope: {}
replace: true,
template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>",
link : link,
}
});
回答by Vignesh Subramanian
You have 3 options for scope
in AngularJS directives
scope
在 AngularJS 指令中有 3 个选项
false
(Uses parent scope)true
(creates own scope and also inherits from parent, i.e you can access items defined in parent scope as well){}
(creates an isolated scope)
false
(使用父作用域)true
(创建自己的范围并从父范围继承,即您也可以访问在父范围中定义的项目){}
(创建一个隔离的范围)
Let me demonstrate this using $rootScope
让我用 $rootScope 来演示一下
app.run(function($rootScope){
$rootScope.firstname = "Root scope name";
$rootScope.rootValue = "Root value";
});
app.directive("sampleDirective",function(){
return{
template:"<div>{{firstname}}{{rootValue}}</div>",
// here rootValue will be accessible as its inherited from parent. You can overwrite this as well
scope : true,
controller:['$scope',sampleDirectiveScope]
};
});
function sampleDirectiveScope($scope){
$scope.firstname = "child scope changing name - ";
};
app.directive("isolatedScopeDirective",function(){
return {
controller:isolatedFunction,
template:" this has isolated scope ,<div>{{rootValue}}</div>",
// here rootValue will not be accessible because it is isolated and not inheriting from parent
scope: {}
};
});
function isolatedFunction($scope){
//define values for this scope
};
Check this live demo
检查这个现场演示