为什么带有隔离范围的指令不会将范围应用于它的DOM元素?

时间:2015-07-12 13:01:48

标签: angularjs angularjs-scope

我正在试图弄清楚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范围可以某种方式调整为孤立的?

2 个答案:

答案 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);