I'm using this library: http://l-lin.github.io/angular-datatables
All is well - I rendered the table Angular way - until the data is large enough to make the performance suffers (only 1,000+ rows).
The solution is to render with ajax or promise as suggested here: angular-datatables the deferRender not working
So for the past three days, I'm stuck at how to transform below codes from angular way to promise
ANGULAR WAY
view.html
<table datatable="ng" dt-options="dtOptions" class="table table-striped table-bordered">
<thead>
<tr>
<th>No</th>
<th>Issue</th>
<th>Meeting No.</th>
<th>Department/Unit</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in issueList | groupBy : 'IssueId' | reverse track by $index">
<td ng-class="{read : value[0].AnswerStatus == 1}">{{$index+1}}</td>
<td>{{value[0].Issue}}</td>
<td>{{value[0].MeetingNo}}</td>
<td>
<table class="table table-striped table-bordered" cellspacing="0" width="100%">
<tbody>
<tr ng-repeat="x in value">
<td width="80%">{{x.Department}}/{{x.Unit}}</td>
<td> <a class="btn btn-default waves-effect m-b-5" ng-click="sendDetail(x.IssueId,x.UnitId)"><i class="fa fa-folder-open"></i> Show </a></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
view.js
$scope.dtOptions =
DTOptionsBuilder.newOptions()
.withOption('stateSave', true)
.withOption('stateDuration', -1)
.withOption('deferRender', true);
$http({
method: 'GET',
url: 'http://issue.json'})
.then(function(response) {
$scope.issueList = response.data;
});
issue.json
[{
"IssueId": "1",
"MeetingNo": "1",
"Issue": "Issue title 1",
"Content": "Content 1",
"AnswerStatus": null,
"UnitId": 1,
"Unit": "Unit 1",
"DepartmentId": 1,
"Department": "Department 1"
}, {
"IssueId": "2",
"MeetingNo": "1",
"Issue": "Issue title 2",
"Content": "Content 2",
"AnswerStatus": null,
"UnitId": 5,
"Unit": "Unit 5",
"DepartmentId": 1,
"Department": "Department 1"
}, {
"IssueId": "2",
"MeetingNo": "1",
"Issue": "Issue title 2",
"Content": "Content 2",
"AnswerStatus": 1,
"UnitId": 6,
"Unit": "Unit 6",
"DepartmentId": 1,
"Department": "Department 1"
}]
Below code is my halfway transformation
PROMISE WAY
view.html
<table datatable="" dt-options="dtOptions" dt-columns="dtColumns" class="table table-striped table-bordered">
</table>
view.js
$scope.dtOptions =
DTOptionsBuilder.fromFnPromise(function() {
var defer = $q.defer();
$http({
method: 'GET',
url: 'http://issue.json'
}).then(function(result) {
defer.resolve(result.data);
});
return defer.promise;
})
.withOption('stateSave', true)
.withOption('stateDuration', -1)
.withOption('deferRender', true); //the very reason to use promise for performance booth
$scope.dtColumns = [
DTColumnBuilder.newColumn(null).withTitle('No')
.renderWith(function(data, type, full, meta) {
return (meta.row+1);
}),
DTColumnBuilder.newColumn('Issue').withTitle('Issue'),
DTColumnBuilder.newColumn('MeetingNo').withTitle('Meeting No.'),
DTColumnBuilder.newColumn('Department').withTitle('Department/Unit'),
];
As you can see, the first column is missing the styling needed for AnswerStatus == 1 and the last column is missing the combine value of Department + '/' + Unit and the button to navigate to another page.
Also please note that the angular way is using groupBy which further complicates my problems :(
Please help. Thanks for your time.
UPDATE:
Actually, I also considering alternative solution, but still facing a road block. I am considering to refactor the json with this:
Array.prototype.groupBy = function(prop) {
return this.reduce(function(groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
}
$scope.dtOptions =
DTOptionsBuilder
.fromFnPromise(function() {
var defer = $q.defer();
$http({
method: 'GET',
url: 'http://issue.json'
}).then(function(result) {
var d = result.data.groupBy('IssueId');
var arr = Object.values(d);
console.log(arr);
defer.resolve(arr);
});
return defer.promise;
})
.withOption('stateSave', true)
.withOption('stateDuration', -1)
.withOption('deferRender', true);
which results in a new array of numbered arrays like this (console.log(arr)):
[
[{
"IssueId": "1",
"MeetingNo": "1",
"Issue": "Issue title 1",
"Content": "Content 1",
"AnswerStatus": null,
"UnitId": 1,
"Unit": "Unit 1",
"DepartmentId": 1,
"Department": "Department 1"
}],
[{
"IssueId": "2",
"MeetingNo": "1",
"Issue": "Issue title 2",
"Content": "Content 2",
"AnswerStatus": null,
"UnitId": 5,
"Unit": "Unit 5",
"DepartmentId": 1,
"Department": "Department 1"
}, {
"IssueId": "2",
"MeetingNo": "1",
"Issue": "Issue title 2",
"Content": "Content 2",
"AnswerStatus": 1,
"UnitId": 6,
"Unit": "Unit 6",
"DepartmentId": 1,
"Department": "Department 1"
}]
]
but I don't know how to proceed with the new array.
createdCell. For the "group by" you must reorganize the JSON so it holdsIssueId's which holds child objects - then you can render out the column with all its child content. You cannot "GroupBy" this way in DataTables, the "normal" approach would be to use child rows. As for theng-clickyou need to use$compileincreatedRow(or simply not use a directive at all, just use a normal click handler) It is certainly doable to refactor the whole thing rather painless, it would just be a looooong answer not suitable for SO.