AngularJS ng-repeat与表中的自定义元素渲染奇怪

时间:2013-09-03 20:14:01

标签: javascript html angularjs angularjs-directive angularjs-ng-repeat

我正在尝试在多个位置重复使用HTML视图的一部分。我想重用的部分是HTML表格中的表格单元格。问题是我在ng-repeat中的自定义指令正在做有趣的事情。我在jsFiddle上重现了这个问题。 jsFiddle中有两个HTML表。第一个是ng-repeat,表格单元格写在视图中,第二个是来自指令my-element的表格单元格。 Chrome开发工具报告呈现的HTML看起来像这样。请注意,自定义元素只出现一次,位于表格之外。

呈现HTML

<div ng-controller="MyCtrl" class="ng-scope">
    table1
    <table class="table table-hover">
      <tbody><!-- ngRepeat: p in people -->
          <tr ng-repeat="p in people" class="ng-scope">
            <td class="ng-binding">Name: Mike</td>
            <td class="ng-binding">Age: 20</td>
          </tr>
          <tr ng-repeat="p in people" class="ng-scope">
            <td class="ng-binding">Name: Peter S</td>
            <td class="ng-binding">Age: 22</td>
          </tr>
      </tbody>
    </table>
    <br>table2
    <my-element class="ng-binding">Name: Age: </my-element>
    <table class="table table-hover">
      <tbody>
        <!-- ngRepeat: p in people -->
        <tr ng-repeat="p in people" class="ng-scope">
        </tr>
        <tr ng-repeat="p in people" class="ng-scope">    
        </tr>
      </tbody>
    </table>
</div>

源HTML

<div ng-controller="MyCtrl">
    table1
    <table class="table table-hover">
        <tr ng-repeat="p in people">
            <td>Name: {{ p.name }}</td>
            <td>Age: {{ p.age }}</td>
        </tr>
    </table>
    <br/>table2
    <table class="table table-hover">
        <tr ng-repeat="p in people">
            <my-element></my-element>
        </tr>
    </table>
</div>

来源JS

var app = angular.module('myApp', []);

app.directive('myElement', function () {
    return {
        restrict: 'E',
        template: '<td>Name: {{ p.name }}</td><td>Age: {{ p.age }}</td>'
    }
});

function MyCtrl($scope) {
    $scope.people = [{
        name: 'Mike',
        age: 20
    }, {
        name: 'Peter S',
        age: 22
    }];
}

请注意,jsFiddle是一个简单的例子,常识会导致根本不使用指令。但是,我的目标代码有一个更大的模板,我想重复使用。我也尝试过使用“ng-include”,结果也差不多。

3 个答案:

答案 0 :(得分:59)

众所周知,

<td>在这样的指令中表现得很奇怪。相反,在父<tr>上使用指令。在此处详细了解此问题:https://github.com/angular/angular.js/issues/1459

<table>
    <tr ng-repeat="p in people" my-element></tr>
</table>

以下是如何进一步改进指令以使其更易于重复使用的方法。

app.directive('myElement', function () {
  return {
    scope: {
      item: '=myElement'
    },
    restrict: 'EA',
    template: '<td>Name: {{item.name}}</td><td>Age: {{item.age}}</td>'
    };
});

传递item的值,如下所示:

  <table>
    <tr ng-repeat="person in people" my-element="person"></tr>
  </table>

Live Demo

答案 1 :(得分:13)

将指令应用于<tr>,如下所示:

<table class="table table-hover">
    <tr my-element blah='p' ng-repeat="p in people"></tr>
</table>

app.directive('myElement', function () {
    return {
        restrict: 'A',
        scope:{
            ngModel: '=blah'
        },
        template: '<td>Name: {{ ngModel.name }}</td><td>Age: {{ ngModel.age }}</td>'
    }
});

Working Demo

答案 2 :(得分:3)

在您的指令中使用replace: true,您的<my-element>将替换为模板中的根项<td>,因此不会混淆HTML。