我的目标是为可重用和轻量级UI元素创建一组灵活的指令.每个都有一个孤立的范围,其中许多都转换了内容.我希望每个指令都是一个黑盒子 – 理想情况下,用户在编写要转换的内容时,不需要知道它是否在内部嵌套了另一个指令.
根据Angular guide to directives:
The transclude option changes the way scopes are nested. It makes it so that the contents of a transcluded directive have whatever scope is outside the directive, rather than whatever scope is on the inside. In doing so, it gives the contents access to the outside scope.
我发现这可以像使用单个指令时所描述的那样工作.但是,如果另一个指令嵌套在那个也转换内容的指令中,那么转换的内容将在外部指令的范围内解析,而不是在外部的范围内解析.这是一个问题,因为它可以防止用户知道他们的被转换内容将在何种范围内得到解决!
例如:(fiddle)
.controller('main', function ($scope) {
$scope.value = '"main"';
$scope.expected = $scope.value;
})
.directive('outer', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: { expected:'=' },
controller: function ($scope) {
$scope.value = '"outer"';
},
template: '<div><inner expected="expected"><span ng-transclude></span></inner></div>'
};
})
.directive('inner', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: { expected:'=' },
controller: function ($scope) {
$scope.value = '"inner"';
},
template: '<div><span>\'value\' is expected to be resolved in scope {{expected}}, and is resolved in scope </span><span ng-transclude></span></div>'
};
})
和HTML:
<div ng-controller="main">
<inner expected="value">
<span>{{value}}</span>
</inner>
<hr/>
<outer expected="value">
<span>{{value}}</span>
</outer>
</div>
在< inner>< / inner>内元素{{value}}在父作用域内被评估为“main”(如预期的那样).但是,在< outer>< / outer>内元素{{value}}在外部的隔离范围内被评估为“外部”(非预期).这样,指令的模板可以影响解析转换内容的范围!
有没有办法解决这个问题?
解决方法:
这确实很糟糕! Angular仅在隔离范围内调用一个父级,如果找不到它需要的内容,则停止查找.要解决此问题,您可以手动调用范围的父级,如下所示:
controller: function ($scope) {
$scope.value = $scope.$parent.value || '"outer"';
}
这将“让”他进一步向上看.