使用ng-transclude似乎在表中不能很好地工作

Mat*_*zke 12 angularjs

我创建了一个简单的指令,用于在<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;
                }
            });
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

它基本上只是跟踪数据集(数组)并检查长度以查看是否有任何数据.如果有,那么我们显示这一行ngIf.

我的HTML看起来像这样

<tr sk-no-result="model.dataSet">Here is my text I want to transclude into my directive</tr>
Run Code Online (Sandbox Code Playgroud)

问题是,被转换的文本只是作为textNode插入到DOM中,<table>而是出现在它上面而不是内部.知道为什么会这样吗?

Bey*_*ers 12

我相信你看到这个的原因不是因为Angular,而是因为浏览器看到<tr>它在预期内是无效的html <td>,因此它将此内容移动到表格之上BEFORE Angular甚至有机会运行做翻译.您可以通过删除任何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>
Run Code Online (Sandbox Code Playgroud)

指令:

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;
    }
  };
}])
Run Code Online (Sandbox Code Playgroud)

请注意,ngTransclude的元素用法,即<ng-transclude></ng-transclude>仅可从Angular 1.3.0-beta.16及更高版本获得.如果您使用的是1.2版本,则需要使用上面示例中的属性用法<div ng-transclude></div>

这是一个工作演示.