我试图制作一个显示名称并允许更改的简单指令。当我在名称页面上放置多个指令时,它们似乎都共享name属性。我做错了什么?
<!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>
答案 0 :(得分:34)
如前面的答案中所述,AngularJS指令的默认行为是共享它们所包含的范围。此行为通过指令定义对象中的scope
参数进行更改。
您可以在AngularJS文档的此部分中查看范围参数的文档:http://docs.angularjs.org/api/ng.$compile#description_comprehensive-directive-api_directive-definition-object
这个论点有三个选项:
scope: false
- 共享范围的默认行为指令包含在
scope: true
- 为指令创建一个新范围,该范围与其他子范围一样,并且原型继承自其父范围
scope: {}
- 创建一个独立的范围,不会从其父范围原型继承
正如您在JSBin示例中所看到的,选项2和3都适用于您的示例。不同之处在于您是否希望隔离新的示波器。
AngularJS指南的指令部分有一个很好的部分,说明为什么隔离范围可以帮助创建具有指令的更好的可重用模块:AngularJS Guide: Isolating the Scope of a Directive
答案 1 :(得分:3)
默认情况下,如果不隔离指令范围,则将与person指令的所有实例共享“外部”范围。使用当前的实现,每次都需要创建一个不同的控制器,以便重用这样的指令。
但是这个漏洞有一个解决方案,它被称为隔离范围。为此,您可以使用指令的范围选项,如下所示:
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,
}
您有here部分的完整示例和说明隔离指令的范围
答案 2 :(得分:2)
默认情况下,指令共享相同的范围。但是如果需要,您可以使用隔离范围作为指令:在指令定义中使用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,
}
});
答案 3 :(得分:1)
AngularJS指令中有scope
的3个选项
false
(使用父范围)true
(创建自己的范围并且也从父级继承,即您也可以访问父范围中定义的项目){}
(创建一个独立的范围)让我用$ 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
};
选中此live demo