我正在试图弄清楚AngularJS范围是如何工作的。我也很好奇为什么他们按照他们的方式工作。我认为以下行为没有意义(fiddle 1)。
<div ng-app="app">
<p>outer element's scope: {{$id}}</p>
<custom-directive isolate-value="Hello!">
<p>inner element's scope: {{$id}}</p>
<p>isolate value: {{isolateValue || 'undefined'}}</p>
</custom-directive>
</div>
function Directive() {
return {
restrict: 'E',
scope: { isolateValue: "@" },
link: function(scope, element, attributes) {
console.log("isolate scope: " + scope.$id);
console.log("isolate value: " + scope.isolateValue);
}
};
}
angular
.module('app',[])
.directive('customDirective', Directive);
我期待视图打印“隔离值:你好!”但我改为“未定义”:
outer element's scope: 1
inner element's scope: 1
isolate value: undefined
DOM元素及其内容保留在父作用域(id = 1)中,从而阻止视图访问正确的作用域(id = 2)。将HTML代码移动到模板中使其按预期工作(fiddle 2)但它与我将该指令用作可重用组件(即相同数据,不同视图)的初始点相冲突。
我使用了transclusion(fiddle 3),但由于需要使用$ parent属性引用正确的范围,因此感觉有点hacky(transclusion再创建一个范围)。
那么,这个指令与DOM隔离范围不匹配背后有一些隐藏的意义吗?或者也许DOM范围可以某种方式调整为孤立的?
答案 0 :(得分:2)
在初始标记中,活动范围始终是父范围。
成为指令的范围是没有意义的,因为你可以有多个指令。例如:
<custom-directive isolate-value="Hello!" ng-show="true">
<p>inner element's scope: {{$id}}</p>
<p>isolate value: {{isolateValue || 'undefined'}}</p>
</custom-directive>
显然,范围不能同时属于customDirective和ngShow。
正如你所说,获得你想要的东西的唯一方法是转换或使用指令模板。
答案 1 :(得分:1)
使用terminal:true和$ compile自己。
http://jsfiddle.net/SE_YOU/rrzrtL4e/
function Directive($compile) {
return {
restrict: 'EA',
terminal: true,
scope: { isolateValue: "@" },
link: function(scope, element, attr) {
console.log("isolate scope: " + scope.$id);
console.log("isolate value: " + scope.isolateValue);
$compile(element.contents())(scope);
}
};
}
angular
.module('app',[])
.directive('customDirective', Directive);