2015-07-12 35 views
-1

我想弄清楚AngularJS范围如何工作。我也很好奇他们为什么以他们的方式工作。我认为以下行为没有意义(fiddle 1)。为什么没有隔离范围的指令将范围应用到它的DOM元素?

<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属性引用正确的作用域(transclusion会创建一个更多作用域),所以感觉有点冒险。

那么,这个指令背后隐藏着一些与DOM隔离范围不匹配的东西吗?或者DOM范围可以以某种方式调整到隔离区?

+0

attributes.isolateValue? – YOU

回答

1

使用终端:true和$自己编译。

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); 
+0

是的,这个工程,谢谢!不过还是想知道,为什么“scope:true”将新范围应用于元素,但“范围:{...}”不适用。 –

+0

@NikolaiKoudelia https://github.com/angular/angular.js/wiki/Understanding-Scopes – YOU

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。

所以,正如你所说,得到你想要的东西的唯一方法是transclude或使用指令模板。