我刚开始研究AngularJS并尝试使用多个插槽transclude实现自定义表指令。 并且面临范围未转移到转移的情况。其他StackOverflow问题中有很多解决方案,但所有这些问题只有在指令模板中才会起作用ng-repeat出现在top元素中,但这不是我的情况。 至少我不能采用所有解决方案。
简化版。 指令:
<span>
<div>Some pagination</div>
<div style="display: inline"><input type="text" placeholder="Search"/></div>
<div style="display: inline">Some filters</div>
<table>
<tbody>
<tr ng-repeat="line in lines" ng-transclude="row">
</tr>
</tbody>
</table>
<div>Some pagination again</div>
</span>
使用指令:
<my-table>
<row>
<td>{{line.col1}}</td>
<td>{{line.col2}}</td>
</row>
</my-table>
Plunkr上的脚本的完整示例: https://plnkr.co/edit/rg43ZdPMGHLBJCTLOoLC
非常感谢任何建议。
答案 0 :(得分:1)
您需要手动使用$ transclude函数并为每一行创建新的子范围。除此之外,如果您正在使用隔离范围(并且您正在使用它),则需要将行传递给指令。 您的链接功能应如下所示:
link: function($scope, $element, $attrs, controller, $transclude) {
var tbody = $element.find('tbody');
$scope.$watch('lines', function (lines) {
tbody.empty();
lines.forEach(function (line) {
var childScope = $scope.$new();
childScope.line = line;
$transclude(childScope, function (content) {
tbody.append('<tr>');
tbody.append(content);
tbody.append('</tr>');
}, null, 'row');
});
});
}
Plunker:https://plnkr.co/edit/MLNZOmoQyMazgIpluMqO?p=preview
但无论如何,这是个坏主意,因为很难以这种方式创建表格。你可以看到孩子不是元素。你必须做一些DOM操作才能使它工作。
答案 1 :(得分:1)
在转换模板中直接引用$scope
创建的ng-repeat
对象的最简单且可能最干净的方法是通过$parent
属性:
<my-table>
<td>{{$parent.line.col1}}</td>
<td>{{$parent.line.col2}}</td>
</my-table>
为转化模板创建的$parent
的{{1}}属性指向最终转换此类模板的目标模板的$scope
(在本例中为{{1}尽管这种被转换的$scope
不是通常意义上的目标$范围的子节点,但是由于这种转换。有关此问题的详细讨论,请参阅this wonderful blog post。
工作plunkr:https://plnkr.co/edit/LoqIMiQVZKlTt5epDnZF?p=preview。
答案 2 :(得分:0)
我发现你并不需要使用属性
所以代码看起来更简单干净:
<body ng-controller="tableCtrl">
<h1>Table test</h1>
<my-table lines="lines"></my-table>
</body>
你的模板:
<span>
<div>Some pagination</div>
<div style="display: inline"><input type="text" placeholder="Search"/></div>
<div style="display: inline">Some filters</div>
<table>
<tbody>
<tr ng-repeat="line in lines">
<td>{{line.col1}}</td>
<td>{{line.col2}}</td>
</tr>
</tbody>
</table>
<div>Some pagination again</div>
</span>
和angular指令:
angular.module('myApp', [])
.directive("myTable", function() {
return {
restrict: 'E',
transclude: true,
scope: {
lines:'=lines',
api: '@'
},
templateUrl: "template.html",
};
})
.controller("tableCtrl", ['$scope', function($scope) {
$scope.lines = [
{col1: "testCol1", col2: "testCol2"},
{col1: "testCol11", col2: "testCol21"}
];
}]);
plunkr中的工作示例:https://plnkr.co/edit/iMxRoD0N3sUXqmViHAQh?p=preview