Javascript 如何使用嵌套指令保留作用域?

Javascript 如何使用嵌套指令保留作用域?,javascript,angularjs,scope,nested,transclusion,Javascript,Angularjs,Scope,Nested,Transclusion,我的目标是为可重用和轻量级UI元素创建一组灵活的指令。每一个都有一个独立的作用域,其中许多都屏蔽了内容。我希望每个指令都是一个黑匣子——理想情况下,用户在编写要转换的内容时不需要知道它是否在内部嵌套了另一个指令 根据报告: transclude选项更改嵌套作用域的方式。它使得转置指令的内容具有指令外部的任何作用域,而不是指令内部的任何作用域。在这样做时,它允许内容访问外部范围 我发现,当使用单个指令时,它的工作原理与所描述的一样。但是,如果该指令中嵌套了另一个指令,该指令也会转包内容,则转包内容

我的目标是为可重用和轻量级UI元素创建一组灵活的指令。每一个都有一个独立的作用域,其中许多都屏蔽了内容。我希望每个指令都是一个黑匣子——理想情况下,用户在编写要转换的内容时不需要知道它是否在内部嵌套了另一个指令

根据报告:

transclude选项更改嵌套作用域的方式。它使得转置指令的内容具有指令外部的任何作用域,而不是指令内部的任何作用域。在这样做时,它允许内容访问外部范围

我发现,当使用单个指令时,它的工作原理与所描述的一样。但是,如果该指令中嵌套了另一个指令,该指令也会转包内容,则转包内容将在外部指令的范围内解析,而不是在外部指令的范围内解析。这是一个问题,因为它阻止用户知道他们的转置内容将在什么范围内得到解决

例如:()

.controller('main',function($scope){
$scope.value='main';
$scope.expected=$scope.value;
})
.directive('outer',function(){
返回{
限制:'E',
替换:正确,
是的,
作用域:{应为:'='},
控制器:功能($scope){
$scope.value=“‘外部’”;
},
模板:“”
};
})
.指令('内部',函数(){
返回{
限制:'E',
替换:正确,
是的,
作用域:{应为:'='},
控制器:功能($scope){
$scope.value='内部';
},
模板:“\'value\”应在作用域{{expected}}中解析,并在作用域中解析
};
})
以及HTML:

<div ng-controller="main">
    <inner expected="value">
        <span>{{value}}</span>
    </inner>
    <hr/>
    <outer expected="value">
        <span>{{value}}</span>
    </outer>
</div>

{{value}}

{{value}}
元素中,
{{value}
在父范围内作为“main”(如预期)进行计算。但是,在
元素中,
{{value}
外部
的隔离范围内被评估为“外部”(非预期)。这样,指令的模板可以影响解析转包内容的范围


有什么办法解决这个问题吗?

这真是太糟糕了!Angular只调用隔离作用域中的一个父级,如果找不到它需要的内容,它将停止查找。要解决此问题,可以手动调用作用域的父级,如下所示:

controller: function ($scope) {
    $scope.value = $scope.$parent.value || '"outer"';
}

这将“让”他看得更远。

经过一番修补,我找到了解决办法。我创建了两个新指令来替换默认的
ng transcude
,并创建了一个助手服务来存储指令之间共享的状态。它们一起让我得到了我所寻找的深刻的隐逸感

第一个将$transclude存储到服务中;它必须在每个指令中使用,这些指令可以在模板中给出可捕获的内容:

controller: ['$transclude', 'TransclusionHelper', function($transclude,TransclusionHelper) {
    TransclusionHelper.setTransclusionFn($transclude);
}],
第二个执行内容到其最终位置的转换;它不必用于仅将其转置内容传递给子级的指令:

link: ['$element','TransclusionHelper', function($element,TransclusionHelper) {
    TransclusionHelper.transclude(function(clone) {
        $element.empty();
        $element.append(clone);
    });
}],

服务中需要一些技巧来管理状态;如果在调用
transclude
之前多次调用了
setTransclusionFn
,调用transclude时,只应存储和使用第一个指令。

为什么要使用隔离作用域?以便可以在任何地方重用该指令,而不会与其父作用域发生意外的交互。但是,您的问题是关于与父作用域交互的?应在父作用域中解决转置的内容(正如angular文档所描述的),但是指令本身不应该与父范围交互(正如angular文档所建议的)。您能告诉我angular docs推荐的隔离范围是什么吗?我想您可能误解了它的用途。这可以奏效,但我正在寻找更灵活的解决方案。这些指令不一定知道嵌套的深度,也不一定知道要链接多少个
$parent
s。
link: ['$element','TransclusionHelper', function($element,TransclusionHelper) {
    TransclusionHelper.transclude(function(clone) {
        $element.empty();
        $element.append(clone);
    });
}],