采用NG-transclude似乎并没有在表中很好地工作很好、并没有、工作、NG

2023-09-13 04:40:37 作者:长发成截

我创建了一个用于显示在&LT一些文本的简单指令; TD> 时,有没有表数据(即没有结果)占用表中的整行。之前我只是在静态文本的< TD> 但现在我希望能够把任何DOM进去。我尝试添加 NG-transclude 来我的指令,但现在它被渲染的元素在陌生的路上。

I created a simple directive that is used to display some text in a <td> when there is no table data (i.e. "No results found" ) takes up the entire row of the table. Before I just had static text in the <td> but now I want to be able to put any DOM into it. I tried adding ng-transclude to my directive but now it is rendering the element in a strange way.

下面是我的指令:

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只是看起来像这样

My html just looks like this

<tr sk-no-result="model.dataSet">Here is my text I want to transclude into my directive</tr>

的问题是,在transcluded文本被插入到DOM作为仅有textNode和正在出现的&所述上面;表&gt; 而不是在它的内部。任何想法,为什么发生这种情况?

The problem is that the transcluded text is being inserted into the DOM as just a textNode and is appearing above the <table> rather than inside of it. Any idea why this is happening?

推荐答案

我相信你看到这种情况的原因是不是因为角,而是浏览器看到,这是一个&LT内部无效的HTML; TR&GT; ,因为它期待&LT; TD&GT; ,结果是这个内容移动到表上方的前角甚至会运行的机会并做transclusion。您可以轻松地删除任何角code测试这一点,刚刚离开的HTML,你会发现结果是完全一样的。

I believe the reason you are seeing this is not because of Angular but rather the browser seeing that it is invalid html inside a <tr> as it is expecting <td> and as a result it moves this content to above the table BEFORE Angular even gets a chance to run and do the transclusion. You can easily test this by removing any Angular code and just leave the HTML and you'll notice the outcome is exactly the same.

下面是您可能能够使用一种解决方法:

Here is a workaround that you might be able to use:

<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,即元素使用&LT; NG-transclude&GT;&LT; / NG-transclude&GT; 只能从角版本1.3.0测试版。 16及以上。如果您使用的是1.2版本中,您需要在上面的例子中使用属性用法&LT; D​​IV NG-transclude&GT;&LT; / DIV&GT;

Note that the element usage of ngTransclude, i.e. <ng-transclude></ng-transclude> is only available from Angular version 1.3.0-beta.16 and above. If you are using a 1.2 release you need to use the attribute usage as in the example above <div ng-transclude></div>

下面是一个工作演示。