HTMLビューの一部を複数の場所で再利用しようとしています。再利用したい部分は、HTMLテーブルのテーブルセルです。問題は、ng-repeat内の私のカスタムディレクティブが面白いことをしていることです。 jsFiddle で問題を再現しました。 jsFiddleには2つのHTMLテーブルがあります。 1つ目は、ビューに書き込まれたテーブルセルを含むng-repeatであり、2つ目は、my-elementディレクティブからのテーブルセルです。 Chrome devツールは、レンダリングされたHTMLがこのように見えることを報告します。カスタム要素は1回だけ表示され、テーブルの外側にあることに注意してください。
レンダリングされた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」も使用してみましたが、結果は似ています。
<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>
次のように、ディレクティブを<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>'
}
});
つかいます replace: true
ディレクティブと<my-element>
はテンプレートのルートアイテム、<td>
ので、これはHTMLを混乱させません。