问题
I am using ng-table with dynamic columns, using the creator's example found at http://bazalt-cms.com/ng-table/example/20
It worked just fine, until i tried to wrap on a directive with transclude, witch caused the headers to disappear as seen on http://plnkr.co/edit/mjYVEf.
index.html
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.2.0-rc3-nonmin" src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>
<script data-require="ng-table@*" data-semver="0.3.1" src="http://bazalt-cms.com/assets/ng-table/0.3.1/ng-table.js"></script>
<script data-require="ng-table-export@0.1.0" data-semver="0.1.0" src="http://bazalt-cms.com/assets/ng-table-export/0.1.0/ng-table-export.js"></script>
<link data-require="ng-table@*" data-semver="0.3.0" rel="stylesheet" href="http://bazalt-cms.com/assets/ng-table/0.3.0/ng-table.css" />
<link data-require="bootstrap-css@*" data-semver="3.0.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="main" ng-controller="DemoCtrl">
<div ng-controller="DemoCtrl">
<transclude-example>
Columns:
<label class="checkbox" ng-repeat="column in columns">
<input type="checkbox" ng-model="column.visible" /> {{column.title}}
</label>
<table ng-table="tableParams" show-filter="true" class="table">
<thead>
<tr>
<th ng-repeat="column in columns" ng-show="column.visible"
class="text-center sortable" ng-class="{
'sort-asc': tableParams.isSortBy(column.field, 'asc'),
'sort-desc': tableParams.isSortBy(column.field, 'desc')
}"
ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
{{column.title}}
</th>
<!--<th>Columns:{{columns.length}}</th>-->
</tr>
</thead>
<tbody>
<tr ng-repeat="user in $data">
<td ng-repeat="column in columns" ng-show="column.visible" sortable="column.field">
{{user[column.field]}}
</td>
</tr>
</tbody>
</table>
</transclude-example>
</body>
</html>
script.js
var app = angular.module('main', ['ngTable']).
controller('DemoCtrl', function($scope, $filter, ngTableParams) {
var data = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.columns = [
{ title: 'Name', field: 'name', visible: true, filter: { 'name': 'text' } },
{ title: 'Age', field: 'age', visible: true }
];
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: 'M' // initial filter
}
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(data, params.orderBy()) :
data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
var originalData = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.originalColumns = [
{ title: 'Name', field: 'name', visible: true, filter: { 'name': 'text' } },
{ title: 'Age', field: 'age', visible: true }
];
$scope.originalTableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: 'M' // initial filter
}
}, {
total: originalData.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ?
$filter('orderBy')(originalData, params.orderBy()) :
originalData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
app.directive('transcludeExample', function() {
return {
restrict: 'EA',
template: '<div ><div><strong>Transcluded Example</strong></div><div ng-transclude></div></div>',
replace: true,
transclude: true
};
});
Has anybody came across the same issue?
回答1:
Define a template for a header, and set a template-header attribute of ng-table.
You can see the code http://plnkr.co/edit/EXVkjabwfjCreNZAY1c2?p=preview
Define template header
<script id="sample_ng_header" type="text/ng-template">
<tr>
<th ng-repeat="column in columns" ng-show="column.visible"
class="text-center sortable" ng-class="{
'sort-asc': tableParams.isSortBy(column.field, 'asc'),
'sort-desc': tableParams.isSortBy(column.field, 'desc')
}"
ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
{{column.title}}
</th>
<!--<th>Columns:{{columns.length}}</th>-->
</tr>
</script>
Set template-header attribute of ng-table with your template
<table ng-table="tableParams" template-header="sample_ng_header" show-filter="true" class="table">
<tbody>
<tr ng-repeat="user in $data">
<td ng-repeat="column in columns" ng-show="column.visible" sortable="column.field">
{{user[column.field]}}
</td>
</tr>
</tbody>
</table>
回答2:
There is a newer way to do this since Feb 2015. I found the following originally linked from this issue on github, but the demo written has been updated since the original.
It makes use of the new ngTableDynamic directive.
The demo is at http://ng-table.com/#/formatting/demo-dynamic-js-values.
I think the main code to pay attention to, assuming you're familiar enough with the rest of ng-table, is
<table ng-table-dynamic="tableParams with cols" show-filter="true" class="table table-bordered table-striped">
<tr ng-repeat="user in $data">
<td ng-repeat="col in $columns">{{user[col.field]}}</td>
</tr>
</table>
The tableParams with cols
part will be parsed, split around the with
to get the table configuration and the column definitions (e.g. $scope.tableParams
and $scope.cols
). You can see the column definitions with code like this:
var usernameCol = {
title: 'Full Name',
titleAlt: 'Name',
sortable: 'name',
filter: { name: 'select' },
filterData: names,
show: true,
field: 'name'
};
var ageCol = { ... }
$scope.cols = [usernameCol, ageCol];
回答3:
Here is my solution: The above solution with template-header did not work for me. The trick is to add the columns in the header and do the same in the data cells
<table ng-table="tableParams" class="table">
<tr>
<th ng-repeat="col in tableCols"
class="text-left sortable header observation-header" ng-class="{
'sort-asc': tableParams.isSortBy(col.field, 'asc'),
'sort-desc': tableParams.isSortBy(col.field, 'desc')
}"
ng-click="tableParams.sorting(col.field, tableParams.isSortBy(col.field, 'desc') ? 'asc' : 'desc')">
<div>{{col.title}}</div>
</th>
</tr>
<tbody>
<tr ng-repeat="dataObj in $data">
<td ng-repeat="col in tableCols" data-title="col.title" sortable="col.field">{{dataObj[col.field]}}</td>
</tr>
></tbody>
</table>
来源:https://stackoverflow.com/questions/24627714/angular-ng-table-dynamic-headers-doesnt-work-inside