我正在尝试创建图表指令(对现有解决方案不感兴趣)。我希望使用bartemplate
的子指令为每个条形图定义模板。我想迭代bartemplate
,所以我想使用ng-repeat
和ng-transclude
的模板可以做到这一点......而角度则会产生错误。
Error: [ngTransclude:orphan] Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: <div ng-repeat="bar in bars track by $index" ng-transclude="" class="ng-scope">
所以你可能会问,为什么要换?我希望能够包含我添加到图表中的任何元素(即标签),而不会干扰<bartemplate>
。
答案 0 :(得分:6)
您的代码有几个问题。首先,您通过在转换中进行转换来进行转换,从而使其复杂化。其次,你正在组合已经进行了转换的指令,例如ng-repeat和试图在其中转换,这是不行的。
我提供了您所需代码的简化版本:
让我试着解释它在做什么。首先,我们有barchart
指令。我冒昧地简化了,但只是让整个身体充当了一个酒吧的模板而不是bar-template
指令。
因为我们设置了transclude: true
,barchart
div中的实际内容被从dom中删除,但是可以通过transclude
函数使用,您可以通过该函数注入控制器$transclude
参数。我们使用此功能并将其保存在我们的控制器上,以便我们稍后可以访问它。
然后,barchart
指令被此模板替换:
<div xmlns="http://www.w3.org/2000/svg">
<div ng-repeat="bar in bars track by $index" render-bar></div>
</div>
请注意,没有ng-transclude
。相反,我们创建自己的指令render-bar
来渲染模板(这避免了与ng-repeat和它自己的转换的任何冲突)。
renderBar
指令非常简单:
directive('renderBar', function(){
return {
require: '^barchart',
link: function(scope, element, attrs, controller){
controller.renderBarTemplate(scope, function(dom){
element.append(dom);
});
}
}
});
首先,我们要求有一个父barchart
指令。在link
函数中,我们可以获取其控制器并访问存储的transclude函数,我们将其命名为renderBarTemplate
。
我们传递的第一个参数是范围,它使函数链接到当前范围(基本上是ng-repeat
提供的范围,它允许我们访问包括bar
的迭代变量。
编译后的dom通过回调(第二个参数)返回,我们可以将其附加到<div>
提供的ng-repeat
。
如果您有任何疑问或需要进一步澄清,请与我们联系。
<强>更新强>:
这是一个允许你保留<bartemplate>
指令的版本:
我添加了bartemplate指令:
directive('bartemplate', function(){
return {
transclude: true,
restrict: 'E',
require: '^barchart',
link: function(scope, element, attrs, barChartController, transclude){
element.remove();
barChartController.renderBarTemplate=transclude;
}
};
})
它现在负责获取其transclude
功能并将其存储在父控制器中。 (因此稍后可以使用render-bar
指令。
另请注意element.remove()
。这不是绝对必要的,只是从html中删除了重新<bartemplate>
标记。