Angular 指令显示在错误的位置

Angular directive is showing in wrong place

我是 Angular 的新手,我正在开发一个使用 ngTable 的应用程序:

var app = angular.module('myApp', ["ngTable"]).controller('mainController', function($scope, NgTableParams) {
    $scope.data = [
        {
            a : "3",
            b : "test" 
        },
        {
            a : "3",
            b : "test" 
        },
        {
            a : "3",
            b : "test" 
        }
    ];
    $scope.tableParams = new NgTableParams({}, { dataset: $scope.data});
});
app.directive('appInfo', function() { 
    return { 
        restrict: 'E', 
        scope: { 
            info: '=infoData' 
        }, 
        template:
        "   <tr> " +
        "       <td filter=\"{ a: 'text'}\" sortable=\"'a'\">{{info.a}}</td> " +
        "       <td filter=\"{ b: 'text'}\" sortable=\"'b'\">{{info.b}}</td> " +
        "   </tr> "
    };  
});

这里是 html:

<div class="main" ng-app="myApp" ng-controller="mainController">
    <table ng-table="tableParams" class="table" show-filter="true">
        <thead>
            <tr>
                <th>A</th>
                <th>B</th>
            </tr>
        </thead>
        <tbody>
            <app-info ng-repeat="info in data" info-data="info" />
        </tbody>
    </table>
</div>

问题是 <app-info> 标签放错了地方,在 table 上面的 div 里面,而不是 tbody。我错过了什么?

发生了什么:

<div class="main" ...>
    <app-info ... />
    <app-info ... />
    ...
    <table ...
</div>

正确的是:

<div class="main" ...>
    <table ...>
        <thead>...</thead>
        <tbody>
            <app-info ... />
            <app-info ... />
            ...
        </tbody>
        ...
</div>

这是一个非常常见的问题,浏览器有特殊的表格呈现方法,并且不适合 angular。它将尝试渲染 <table> 通过搜索 trtdthead 等,然后剔除不应该出现在这里的内容,例如 app-info。它会将未知元素放在 table 之上,然后渲染其余元素。

  • Angular table row directive not rendering inside table
  • Angular Directive table rows issue

解决它的一种方法是使您的指令成为属性而不是元素:

restrict: 'A', 

<tbody>
     <tr app-info ng-repeat="info in data" info-data="info">
     </tr>
</tbody>

这样浏览器就不会删除 app-info,并且 angular 将有时间正确呈现。

理论上您可以在指令配置中使用 replace : true,但它已被弃用,因为存在已知错误:

replace ([DEPRECATED!], will be removed in next major release - i.e. v2.0)

我认为浏览器不喜欢在 tbody 中使用 app-info 标签。在 Angular.js 发挥它的魔力之前,浏览器会尝试 "fix" 您的无效 HTML,方法是将 app-info 移到 table.

之外

您可以尝试更改 restrict: 'A' 并改用 <tr app-info...

但是,通常不希望在模板的根部包含 table 相关标签。