angularjsajaxsortingpaginationngtable

How to avoid loading data from server every time doing sorting/paging with ngtable


I am using ngtable (1.0.0) to display records fetched from server side. My controller js looks like this:

ristoreApp.controller("fmCtrl",
    ['$scope', '$filter', 'fmFactory', 'NgTableParams', function($scope, $filter, fmFactory, NgTableParams) {
        var self = this;
        $scope.selection = '0';
        $scope.fmSearch = function () {
            if ($scope.selection == '0') {
                self.tableParams = new NgTableParams({
                    page: 1,            // show first page
                    count: 10,          // count per page
                    sorting: {
                        frReportId: 'asc'
                    }
                }, {
                    getData: function (params) {
                        return fmFactory.getAll()
                            .then(function(response) {
                                var reports = response.data;
                                params.total(reports.length);
                                console.log(params.total());
                                var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports;
                                return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count());
                        });
                    }
                });
            }
        }
    }]
)

HTML for the table:

<div ng-controller="fmCtrl as fm">
    <div class="container">
        <div class="row top-margin-80">
            <div class="col-md-12">
                <div class="input-group" id="adv-search">
                    <input type="text" class="form-control" ng-model="keyword" placeholder="Enter MRN or report ID" />
                    <div class="input-group-btn">
                        <div class="btn-group" role="group">
                            <div class="dropdown dropdown-lg">
                                <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><span class="caret"></span></button>
                                <div class="dropdown-menu dropdown-menu-right" role="menu">
                                    <form class="form-horizontal" role="form">
                                        <div class="form-group">
                                            <label for="filter">Search by</label>
                                            <select class="form-control" ng-model="selection">
                                                <option value="0" selected>All Reports</option>
                                                <option value="1" >MRN</option>
                                                <option value="2">ReportID</option>

                                            </select>
                                        </div>
                                        <div class="form-group">
                                            <input class="form-control" type="text" ng-model="optionword" ng-hide="selection == '0'"/>
                                        </div>
                                    </form>
                                </div>
                            </div>
                            <button type="button" class="btn btn-primary" ng-click="fmSearch()"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="container">
        <table ng-table="fm.tableParams" class="table table-bordered table-striped table-condensed" show-filter="false">
            <tr ng-repeat="report in $data">
                <td data-title="'ReportId'" filter="{frReportId: 'text'}" sortable="'frReportId'" class="text-center">
                    {{report.frReportId}}</td>
                <td data-title="'BlockId'" filter="{frBlockId: 'text'}" sortable="'frBlockId'" class="text-center">
                    {{report.frBlockId}}</td>
                <td data-title="'MRN'" filter="{mrn: 'text'}" sortable="'mrn'" class="text-center">
                    {{report.mrn}}</td>
                <td data-title="'Name'" filter="{frFullName: 'text'}" sortable="'frFullName'" class="text-center">
                    {{report.frFullName}}</td>
                <td data-title="'Diagnosis'" filter="{frDiagnosis: 'text'}" sortable="'frDiagnosis'" class="text-center">
                    {{report.frDiagnosis}}</td>
                <td data-title="'File'" class="text-center"><a ng-href="{{report.filepath}}">{{report.frReportId}}.xml</a>
                    </td>

            </tr>
        </table>
    </div>
</div>

It works, well sort of. Problem is whenever I click on the titles to sort and page button to go to next page, it makes an ajax call to server to retrieve data again. I have over 2000 records in the database, every time I do something to the table, it takes 5 seconds to respond which is very annoying. How do I make it load the data only the first time and cache it on client side for future manipulation?


Solution

  • Finally got it to work. Solution is to move the ajax call var Ajax = fmFactory.getAll(); outside ngtable constructor.

                    var Ajax = fmFactory.getAll();
                    self.tableParams = new NgTableParams({
                        page: 1,            // show first page
                        count: 10,          // count per page
                        sorting: {
                            frReportId: 'asc'
                        }
                    }, {
                        getData: function (params) {
                            return Ajax.then(function(response) {
                                    var reports = response.data;
                                    params.total(reports.length);
                                    console.log(params.total());
                                    var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports;
                                    return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count());
                            });
                        }
                    });