我创建了一个简单的指令,用于在没有表数据(即“找不到结果”)占用表的整行时在<td>
中显示一些文本。之前我在<td>
中只有静态文本,但现在我希望能够将任何DOM放入其中。我尝试将ng-transclude
添加到我的指令中,但现在它以一种奇怪的方式呈现元素。
这是我的指示:
app.directive('skNoResult', ['$rootScope', function () {
return {
restrict: 'A',
replace: true,
transclude: true,
template: '<tr ng-if="!hasResult"><td class="left" colspan="{{ colSpan }}"><ng-transclude></ng-transclude></td></tr>',
link: function (scope, elem, attrs, ctrl) {
var span = angular.element(elem).parents('tbody').siblings('thead').find('tr').children().length;
scope.colSpan = span;
scope.$watch(attrs.skNoResult, function (list) {
if (list.length) {
scope.hasResult = true;
} else {
scope.hasResult = false;
}
});
}
};
}]);
它基本上只是跟踪数据集(数组)并检查长度以查看是否有任何数据。如果有,那么我们会使用ngIf
显示此行。
我的html看起来像这样
<tr sk-no-result="model.dataSet">Here is my text I want to transclude into my directive</tr>
问题在于,被转换的文本只是作为textNode插入到DOM中,并且出现在<table>
上方而不是内部。知道为什么会这样吗?
答案 0 :(得分:12)
我相信你看到这个的原因不是因为Angular,而是浏览器在<tr>
内看到它是无效的html,因为它期待<td>
因此它移动了这个内容在角度之上,BEFORE甚至有机会运行并进行转换。您可以通过删除任何Angular代码轻松测试,只需保留HTML,您就会注意到结果完全相同。
以下是您可以使用的解决方法:
<tr ng-if="!model.dataSet.length">
<td sk-no-result="model.dataSet">Here is my text I want to transclude into my directive</td>
</tr>
指令:
app.directive('skNoResult', ['$rootScope', function () {
return {
restrict: 'A',
replace: true,
transclude: true,
template: '<td class="left" colspan="{{ colSpan }}"><div ng-transclude></div></td>',
link: function (scope, elem, attrs) {
var span = angular.element(elem).parents('tbody').siblings('thead').find('tr').children().length;
scope.colSpan = span;
}
};
}])
请注意,ngTransclude的元素用法,即<ng-transclude></ng-transclude>
仅适用于Angular版本1.3.0-beta.16及更高版本。如果您使用的是1.2版本,则需要使用上面示例<div ng-transclude></div>
这是一个有效的demo。