angular smart table not working - angularjs

I am using smart table http://lorenzofox3.github.io/smart-table-website/ and I am trying to follow pipe/ajax plugin example. But its not showing any data. this is what I have in my html
<div ng-controller="AboutCtrl">
<table class="table" st-pipe="mc.callServer" st-table="mc.displayed">
<thead>
<tr>
<th st-sort="id">id</th>
<th st-sort="name">name</th>
<th st-sort="age">age</th>
<th st-sort="saved">saved people</th>
</tr>
<tr>
<th><input st-search="id"/></th>
<th><input st-search="name"/></th>
<th><input st-search="age"/></th>
<th><input st-search="saved"/></th>
</tr>
</thead>
<tbody ng-show="!mc.isLoading">
<tr ng-repeat="row in mc.displayed">
<td>{{row.id}}</td>
<td>{{row.name}}</td>
<td>{{row.age}}</td>
<td>{{row.saved}}</td>
</tr>
</tbody>
<tbody ng-show="mc.isLoading">
<tr>
<td colspan="4" class="text-center">Loading ... </td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="text-center" st-pagination="" st-items-by-page="10" colspan="4">
</td>
</tr>
</tfoot>
</table>
</div>
and here is my js
angular.module('eventsApp')
.controller('AboutCtrl', ['Resource', function (service) {
var ctrl = this;
this.displayed = [];
this.callServer = function callServer(tableState) {
ctrl.isLoading = true;
var pagination = tableState.pagination;
var start = pagination.start || 0; // This is NOT the page number, but the index of item in the list that you want to use to display the table.
var number = pagination.number || 10; // Number of entries showed per page.
service.getPage(start, number, tableState).then(function (result) {
ctrl.displayed = result.data;
tableState.pagination.numberOfPages = result.numberOfPages;//set the number of pages so the pagination can update
ctrl.isLoading = false;
});
};
}]).factory('Resource', ['$q', '$filter', '$timeout', function ($q, $filter, $timeout) {
//this would be the service to call your server, a standard bridge between your model an $http
// the database (normally on your server)
var randomsItems = [];
function createRandomItem(id) {
var heroes = ['Batman', 'Superman', 'Robin', 'Thor', 'Hulk', 'Niki Larson', 'Stark', 'Bob Leponge'];
return {
id: id,
name: heroes[Math.floor(Math.random() * 7)],
age: Math.floor(Math.random() * 1000),
saved: Math.floor(Math.random() * 10000)
};
}
for (var i = 0; i < 1000; i++) {
randomsItems.push(createRandomItem(i));
}
//fake call to the server, normally this service would serialize table state to send it to the server (with query parameters for example) and parse the response
//in our case, it actually performs the logic which would happened in the server
function getPage(start, number, params) {
var deferred = $q.defer();
var filtered = params.search.predicateObject ? $filter('filter')(randomsItems, params.search.predicateObject) : randomsItems;
if (params.sort.predicate) {
filtered = $filter('orderBy')(filtered, params.sort.predicate, params.sort.reverse);
}
var result = filtered.slice(start, start + number);
$timeout(function () {
//note, the server passes the information about the data set size
deferred.resolve({
data: result,
numberOfPages: Math.ceil(filtered.length / number)
});
}, 1500);
return deferred.promise;
}
return {
getPage: getPage
};
}]);
and this is what my browser show

Try change this
<div ng-controller="AboutCtrl">
to
<div ng-controller="AboutCtrl as mc">

</script>-->
</script>
</script>
</script>-->
<script>
angular.module('eventsApp', ['smart-table', 'ngSanitize', 'ngRoute'])
.controller('AboutCtrl', ["$scope", "Resource", function ($scope, Resource) {
var ctrl = this;
this.displayed = Resource.GetData();
this.callServer = function callServer(tableState) {
ctrl.isLoading = true;
var pagination = tableState.pagination;
var start = pagination.start || 0; // This is NOT the page number, but the index of item in the list that you want to use to display the table.
var number = pagination.number || 10; // Number of entries showed per page.
Resource.getPage(start, number, tableState).then(function (result) {
ctrl.displayed = result.data;
tableState.pagination.numberOfPages = result.numberOfPages; //set the number of pages so the pagination can update
ctrl.isLoading = false;
});
};
} ]).factory('Resource', ['$q', '$filter', '$timeout', function ($q, $filter, $timeout) {
//this would be the service to call your server, a standard bridge between your model an $http
// the database (normally on your server)
var randomsItems = [];
function GetData() {
function createRandomItem(id) {
var heroes = ['Batman', 'Superman', 'Robin', 'Thor', 'Hulk', 'Niki Larson', 'Stark', 'Bob Leponge'];
return {
id: id,
name: heroes[Math.floor(Math.random() * 7)],
age: Math.floor(Math.random() * 1000),
saved: Math.floor(Math.random() * 10000)
};
}
for (var i = 0; i < 1000; i++) {
randomsItems.push(createRandomItem(i));
}
return randomsItems;
}
//fake call to the server, normally this service would serialize table state to send it to the server (with query parameters for example) and parse the response
//in our case, it actually performs the logic which would happened in the server
function getPage(start, number, params) {
var deferred = $q.defer();
var filtered = params.search.predicateObject ? $filter('filter')(randomsItems, params.search.predicateObject) : randomsItems;
if (params.sort.predicate) {
filtered = $filter('orderBy')(filtered, params.sort.predicate, params.sort.reverse);
}
var result = filtered.slice(start, start + number);
$timeout(function () {
//note, the server passes the information about the data set size
deferred.resolve({
data: result,
numberOfPages: Math.ceil(filtered.length / number)
});
}, 1500);
return deferred.promise;
}
return {
getPage: getPage,
GetData: GetData
};
} ]);
</script>
</head>
<body ng-app="eventsApp">
<div ng-controller="AboutCtrl as mc">
<table class="table" st-pipe="mc.callServer" st-table="mc.displayed">
<thead>
<tr>
<th st-sort="id">id</th>
<th st-sort="name">name</th>
<th st-sort="age">age</th>
<th st-sort="saved">saved people</th>
</tr>
<tr>
<th><input st-search="id"/></th>
<th><input st-search="name"/></th>
<th><input st-search="age"/></th>
<th><input st-search="saved"/></th>
</tr>
</thead>
<tbody ng-show="!isLoading">
<tr ng-repeat="row in mc.displayed">
<td>{{row.id}}</td>
<td>{{row.name}}</td>
<td>{{row.age}}</td>
<td>{{row.saved}}</td>
</tr>
</tbody>
<tbody ng-show="mc.isLoading">
<tr>
<td colspan="4" class="text-center">Loading ... </td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="text-center" st-pagination="" st-items-by-page="10" colspan="4">
</td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>

Related

JsonResult method not calling through angular call

JsonResult method not calling through $http call,
I am working on a project that uses ASP.NET MVC, AngularJS I am calling a mvc controller from AngularJS. I am getting an jsonresult as in the call to a MVC controller from AngularJS .
this is the result
[
{
"Branch_ID": 1,
"Branch_Name": "sdsds",
"Branch_Address": "sfsdfsdf",
"Branch_email": "sdfsdfsdf",
"Branch_Notes": "sfsffsfd",
"Branch_Manager": null,
"Branch_Phone": null,
"Branch_TimeFrom": "/Date(-2208996000000)/",
"Branch_TimeTo": "/Date(-2208996000000)/",
"saturday": false,
"sunday": false,
"monday": false,
"tuesday": false,
"wednesday": false,
"thursday": false,
"friday": false,
"Departments": null
}
]
branches controller
public class BranchesController : Controller
{
private IRepositoryBase<Branches> BrancheRepository;
public BranchesController(IRepositoryBase<Branches> brancheRepository)
{
this.BrancheRepository = brancheRepository;
}
// GET: Branches
public JsonResult Index()
{
var branches = BrancheRepository.GetAll();
//if (!String.IsNullOrEmpty(searchString))
//{
// branches = branches.Where(s => s.Branch_Name.ToUpper().Contains(searchString.ToUpper()));
//}
return Json(branches, JsonRequestBehavior.AllowGet);
}
}
Index.cshtml
<div class="container" ng-controller="branch-controller">
<div class="panel panel-info">
<div class="panel-heading">
Branch Details - Grid CRUD operations
</div>
<table class="table table-bordered">
<thead style="background-color:lightblue;">
<tr>
<th> Branch Address</th>
<th> Branch Email</th>
<th>Branch Name</th>
<th>Branch Notes</th>
<th> Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="branche in Branches">
<td>{{branche.Branch_ID}}</td>
<td>{{branche.Branch_Address}}</td>
<td>{{branche.Branch_email}}</td>
<td>{{branche.Branch_Name}}</td>
<td>{{branche.Branch_Notes}}</td>
<td style="width:200px;">
Update
Delete
</td>
</tr>
</tbody>
</table>
</div>
Module.js
var myapp;
(function () {
myapp = angular.module('my-branches', []);
})();
Controller.js
myapp.controller('branch-controller', function ($scope, branchService) {
//Loads all branch records when page loads
loadBranches();
function loadBranches() {
var BrancheRecords = branchService.getAllBranches();
BrancheRecords.then(function (data) {
//success
$scope.Branches = data;
},
function (error) {
console.log(error);
alert("Error occured while fetching branche list...");
});
}
});
Service.js
myapp.service('branchService', function ($http) {
this.getAllBranches = function () {
return $http.get("/Branches/Index").then(function (response) {
return response.data;
});
};
});
I have changed my code to this code to solve the issue
FetchData.js
var app = angular.module('mybranches', []);
app.service("myService", function ($http) {
//get All Branches
this.getAllBranches = function () {
return $http.get("Branches/GetAllBranches");
};
});
app.controller("branchcontroller", function ($scope, myService) {
getAllBranches();
function getAllBranches() {
var getData = myService.getAllBranches();
getData.then(function (response) {
$scope.Branches = response.data;
}, function (error) {
console.log(error);
alert('Error in getting records');
});
}
});
public class BranchesController : Controller
{
private IRepositoryBase<Branches> BrancheRepository;
public BranchesController()
{
this.BrancheRepository = new BranchesRepository(new HrmDBContext());
}
public BranchesController(IRepositoryBase<Branches> brancheRepository)
{
this.BrancheRepository = brancheRepository;
}
// GET: Branches
[HttpGet]
public ActionResult Index()
{
// var branches = BrancheRepository.GetAll();
//if (!String.IsNullOrEmpty(searchString))
//{
// branches = branches.Where(s => s.Branch_Name.ToUpper().Contains(searchString.ToUpper()));
//}
return View();
}
[HttpGet]
public JsonResult GetAllBranches()
{
var branches = BrancheRepository.GetAll();
//if (!String.IsNullOrEmpty(searchString))
//{
// branches = branches.Where(s => s.Branch_Name.ToUpper().Contains(searchString.ToUpper()));
//}
//return new JsonResult { Data = branches, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
return Json(branches, JsonRequestBehavior.AllowGet);
// return new JsonResult{Data = branches, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
}
}
Index.cshtml
<div>
<div class="container" ng-controller="branchcontroller">
<div class="panel panel-info">
<div class="panel-heading">
Branch Details - Grid CRUD operations
</div>
<table class="table table-bordered">
<thead style="background-color:lightblue;">
<tr>
<th> Branch Address</th>
<th> Branch Email</th>
<th>Branch Name</th>
<th>Branch Notes</th>
<th> Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="branche in Branches track by $index">
<td>{{branche.Branch_ID}}</td>
<td>{{branche.Branch_Address}}</td>
<td>{{branche.Branch_email}}</td>
<td>{{branche.Branch_Name}}</td>
<td>{{branche.Branch_Notes}}</td>
<td style="width:200px;">
Update
Delete
</td>
</tr>
</tbody>
</table>
</div>
</div>

Ng-Table is not binding from NgTableParams with server side data

Unable to bind the table with data i.e. collected from service.
Controller code is as:
app.controller('outletTypeController', ['$scope', '$location', '$timeout', 'outletTypesService', '$uibModal', 'NgTableParams', '$q', '$log',
function ($scope, $location, $timeout, outletTypesService, $uibModal, NgTableParams, $q, $log) {
$scope.message = "";
$scope.animationsEnabled = true;
$scope.outletTypes = [];
//To Load Outlet Types in same controller
$scope.LoadOutletTypes = function () {
outletTypesService.getOutletTypes().then(function (results) {
$scope.outletTypes = results.data.Result;
}, function (error) {
var errors = [];
if (response.data != null) {
for (var key in response.data.modelState) {
for (var i = 0; i < response.data.modelState[key].length; i++) {
errors.push(response.data.modelState[key][i]);
}
}
}
$scope.message = "Failed to load data due to:" + errors.join(' ');
});
};
//To Bind OutletType With Options in same controller
$scope.outletTypeWithOptions = function () {
//to set outletTypes
$scope.LoadOutletTypes();
var initialParams = {
count: 2 // initial page size
};
var initialSettings = {
// page size buttons (right set of buttons in demo)
counts: [10, 50, 100],
// determines the pager buttons (left set of buttons in demo)
paginationMaxBlocks: 5,
paginationMinBlocks: 1,
dataset: $scope.outletTypes
};
return new NgTableParams(initialParams, initialSettings);
};
and HTML View Code is as:
<div id="body" ng-controller="outletTypeController">
<table ng-table="outletTypeWithOptions" class="table table-striped" show-filter="true" cellspacing="0" width="100%">
<tr data-ng-repeat="type in $data">
<td title="'Logo'" class="text-center">
<div class="logoImg">
<img src="images/halalpalc.png" width="30" />
</div>
</td>
<td title="'Outlet Type'" filter="{ OTypeName: 'text'}" sortable="'OTypeName'">
{{ type.OTypeName }}
</td>
<td title="'Icon Rated'">I R</td>
<td title="'Icon Unrated'">I U</td>
<td title="'Status'" class="text-center status">
{{ type.IsActive}}
</td>
<td title="'Action'" class="text-center">
<!--<a href="#" class="editAction" data-toggle="modal" data-target="#myModal" title="Edit">
<img src="images/SVG_icons/edit_action.svg" />
</a>-->
<button data-ng-click="open()" class="btn btn-warning">Edit</button>
<!--<img src="images/SVG_icons/close_action.svg" />-->
</td>
</tr>
</table>
</div>
But unable to bind the data, However I try to bind it with Static Data it's properly working.
Here $scope.LoadOutletTypes is an async method call, which will asynchronously populate $scope.outletTypes with results. Rest of the code after LoadOutletTypes method call won't wait for result instead proceeds for execution, which will populate dataset in initialSettings object with null value(If it was unable to load the outlet types in time. But this will work for static data).
Try the below code..
$scope.LoadOutletTypes = function () {
outletTypesService.getOutletTypes().then(function (results) {
$scope.outletTypes = results.data.Result;
$scope.setOutletTypeWithOptions();
}, function (error) {
var errors = [];
if (response.data != null) {
for (var key in response.data.modelState) {
for (var i = 0; i < response.data.modelState[key].length; i++) {
errors.push(response.data.modelState[key][i]);
}
}
}
$scope.message = "Failed to load data due to:" + errors.join(' ');
});
};
$scope.setOutletTypeWithOptions = function () {
var initialParams = {
count: 2 // initial page size
};
var initialSettings = {
// page size buttons (right set of buttons in demo)
counts: [10, 50, 100],
// determines the pager buttons (left set of buttons in demo)
paginationMaxBlocks: 5,
paginationMinBlocks: 1,
dataset: $scope.outletTypes
};
$scope.NgTableParams = new NgTableParams(initialParams, initialSettings);
};
<div id="body" ng-controller="outletTypeController">
<table ng-table="NgTableParams" ng-init="LoadOutletTypes()" class="table table-striped" show-filter="true" cellspacing="0" width="100%">
<tr data-ng-repeat="type in $data">....

How to use select filter with static values on async (server-side) ngTable

I'm using ngTable 0.3.3 and am doing a async call to populate the table (pagination also done on server side). Here's my code:
var data = [];
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
}, {
getData: function($defer, params) {
// getData gets called when you click on a different page in the pagination links.
// get the page number and size from params.$params
var pageNumber = params.$params.page;
var pageSize = params.$params.count;
// set up the query parameters as expected by your server
var mm = params.filter();
var queryParams = {"page_size":pageSize, "page_number":pageNumber, "sorting": params.sorting(), role: mm.role, id: mm.id, email: mm.email};
$log.log(mm.role);
// $log.log(mm.role, mm.email);
User.getCount().then(function (total) {
User.query(queryParams).then(function (result) {
params.total(total);
$defer.resolve(result);
});
});
}
});
with this html:
<table ng-table="tableParams" show-filter="true" class="table table-custom">
<tr ng-repeat="user in $data">
<td data-title="'Name'">
{{user.first_name}} {{user.last_name}}
</td>
<td data-title="'Role'" sortable="'role'" filter="{ 'role': 'text' }">
{{user._role}}
</td>
<td data-title="'Email'" sortable="'email'" filter="{ 'email': 'text' }">
{{user.email}}
</td>
<td data-title="'Created date'">
{{user.created_at | date: 'dd MMM yyyy'}}
</td>
<td data-title="'Edit'">
<a ui-sref="app.users.edit({userId: user.id})">Edit</a>
</td>
<td data-title="'Edit'">
<a ng-click="deleteUser(user.id)">Delete</a>
</td>
</tr>
</table>
And both filtering and pagination works as expected. You can see I have a $log call which tells me when the filter is being triggered while I type in the text field. Now I'm trying to get the role as a select rather than a text field, so I changed my code like so:
$scope.roles = function (column) {
var def = $q.defer();
var docType = [{role: 'admin'}, {role: 'customer'}, {role: 'singer'}, {role: 'voiceArtist'}];
def.resolve(docType);
return def;
};
var data = [];
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
}, {
getData: function($defer, params) {
// getData gets called when you click on a different page in the pagination links.
// get the page number and size from params.$params
var pageNumber = params.$params.page;
var pageSize = params.$params.count;
// set up the query parameters as expected by your server
var mm = params.filter();
var queryParams = {"page_size":pageSize, "page_number":pageNumber, "sorting": params.sorting(), role: mm.role, id: mm.id, email: mm.email};
$log.log(mm.role);
// $log.log(mm.role, mm.email);
User.getCount().then(function (total) {
User.query(queryParams).then(function (result) {
params.total(total);
$defer.resolve(result);
});
});
}
});
And this html:
<table ng-table="tableParams" show-filter="true" class="table table-custom">
<tr ng-repeat="user in $data">
<td data-title="'Name'">
{{user.first_name}} {{user.last_name}}
</td>
<td data-title="'Role'" sortable="'role'" filter="{ 'role': 'text' }">
{{user._role}}
</td>
<td data-title="'Role1'" filter="{role: 'select'}" filter-data="roles($column)">{{user._role}}</td>
<td data-title="'Email'" sortable="'email'" filter="{ 'email': 'text' }">
{{user.email}}
</td>
<td data-title="'Created date'">
{{user.created_at | date: 'dd MMM yyyy'}}
</td>
<td data-title="'Edit'">
<a ui-sref="app.users.edit({userId: user.id})">Edit</a>
</td>
<td data-title="'Edit'">
<a ng-click="deleteUser(user.id)">Delete</a>
</td>
</tr>
</table>
The roles (that I want to populate the select from) is a static array with five elements in it. I can see the select on the Role column, but is empty (doesn't show admin, customer, etc) and it doesn't trigger the filter. When I select an item, nothing happens anywhere. Wha am I missing here?
PS: I've seen similar questions and have even tried their plunker when was available, but the questions I've found they either use async values for the select (which I don't want to) or the whole data is static, which again, I don't want to. Any help would be much appreciated.
EDIT
How I got it to work:
My js code:
$scope.roles = function (column) {
var def = $q.defer();
var docType = [{id: 'admin', title: 'Admin'}, {id: 'customer', title: 'Customer'}, {id: 'singer', title: 'Singer'}, {id: 'voiceArtist', title: 'Voice Artist'}];
def.resolve(docType);
return def;
};
var data = [];
$scope.deleteUser = function (id) {
User.get(id).then(function (result) {
$scope.tmpUser = result;
$scope.tmpUser.remove().then(function (result) {
if (result) {
$scope.showAlert('User deleted successfully.', 'success');
var n = true;
angular.forEach(data, function (v, k) {
if ($scope.tmpUser.id === v.id) {
if (n) {
data.splice(k, 1);
$scope.tableParams.reload();
n = false;
}
}
});
}
});
});
};
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
}, {
getData: function($defer, params) {
// getData gets called when you click on a different page in the pagination links.
// get the page number and size from params.$params
var pageNumber = params.$params.page;
var pageSize = params.$params.count;
// set up the query parameters as expected by your server
var mm = params.filter();
var queryParams = {"page_size":pageSize, "page_number":pageNumber, "sorting": params.sorting(), role: mm.role, id: mm.id, email: mm.email};
User.getCount().then(function (total) {
User.query(queryParams).then(function (result) {
params.total(total);
$defer.resolve(result);
});
});
}
});
Its important to note that the array you pass must in the format of [{id:'someId', title: 'SomeTitle'}, {...}]
Your select is not populated because you're not waiting for the promise to resolve.
Here's a plunker that I stumbled upon when I faced this issue a few months ago:
plnkr.co/edit/XJo9rp?p=preview
Try something like that:
function getData() {
return $q.when([{role: 'admin'},...]);
}
var promise = getData();
Which is the short version for:
function getData() {
var def = $q.defer();
var docType = [{role: 'admin'},...];
def.resolve(docType);
return def;
}
var promise = getData();
and your scope function:
$scope.roles = function(column) {
var select = promise.then(function(results) {
return results;
})
return select;
};

Display TimeSpan type Data in Angularjs Listing

Trying to show time in table but it shows me time in this format
{"Hours":16,"Minutes":8,"Seconds":45,"Milliseconds":0,"Ticks":581250000000,"Days":0,"TotalDays":0.6727430555555556,"TotalHours":16.145833333333332,"TotalMilliseconds":58125000,"TotalMinutes":968.75,"TotalSeconds":58125}
while i want it to be displayed in this format
"12:13:20"
In Html file i does listing like this
<table>
<thead>
<tr>
<th>Start Time</th>
<th>End Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in Festivals">
<td>{{item.StartTime}}</td>
<td>{{item.EndTime}}</td>
</tr>
</tbody>
</table>
Angular controller code where i am initializing data
var app = angular.module('myApp');
app.controller('SeasonCtrl', [
'$scope', '$http', 'seasonService', function ($scope, $http, seasonService) {
$scope.Seasons = [];
seasonService.GetAllSeasons = function () {
seasonService.getSeasons().success(function (data) {
$scope.Seasons = data.data;
})
}
seasonService.GetAllSeasons();
}
]);
C# Code i am sending data to angular controller
public JsonResult GetAllSeasons()
{
var data = _seasonManager.AllSeasons();
if (data != null)
{
var list = data.Select(r => new
{
r.StartTime,
r.EndTime
});
return Json(new { data = list }, JsonRequestBehavior.AllowGet);
}
return null;
}
I have just tried this and its solved my problem
In Html
<table>
<thead>
<tr>
<th>Start Time</th>
<th>End Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in Festivals">
<td ng-bind='timeFunction(item.StartTime)'></td>
<td ng-bind='timeFunction(item.EndTime)'></td>
</tr>
</tbody>
</table>
In Angular Controller
$scope.timeFunction = function (timeObj) {
var min = timeObj.Minutes < 10 ? "0" + timeObj.Minutes : timeObj.Minutes;
var sec = timeObj.Seconds < 10 ? "0" + timeObj.Seconds : timeObj.Seconds;
var hour = timeObj.Hours < 10 ? "0" + timeObj.Hours : timeObj.Hours;
return hour + ':' + min + ':' + sec;
};
This solution uses a filter and Moment.js.
In JS:
angular.module('app')
.filter('showTimeSpan', function () {
return function (timeObj, format) {
return moment(timeObj, "HH:mm").format(format);
};
});
In HTML:
<p>{{activity.startTime | showTimeSpan:"hh:mm a"}}</p>

Angular JS ngInfiniteScroll with LimitTo

I'm using ngInfiniteScroll ng-module for my pagination. When i scroll down the page i'm appending 20 records to my data table. By doing that, i'm actually running a http request each time ("not good for performance).
I've been doing some research and came across adding a LimitTo with the ngInfiniteScroll. Not sure how to implement this. Could someone please give me any suggestions.
<table infinite-scroll='tF.loadMore()' infinite-scroll-disabled='tF.isBusy' infinite-scroll-distance='3' class="responsive">
<thead>
<tr>
<th>FIRST NAME</th>
<th>LAST NAME</th>
<th>USERNAME</th>
<th>EMAIL</th>
<th>CREATED DATE</th>
<th>STATUS</th>
<th>IS ONLINE</th>
<th>ACTIONS</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in tF.items | filter:searchFilter">
<td>{{item.FirstName}}</td>
<td>{{item.LastName}}</td>
<td>{{item.Username}}</td>
<td>{{item.Email}}</td>
<td>{{item.CreatedDate | date:'medium'}}</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot ng-show='tF.isBusy'>
<tr>
<td colspan="9"><spinner show="tF.isBusy" /><span class="bold">{{tF.status}}</span> </td>
</tr>
</tfoot>
</table>
/**** CONTROLLER.JS *****/
var vm = this;
var page = 0;
vm.items = [];
vm.isBusy = false;
vm.loadMore = function ()
{
if(vm.isBusy) return;
vm.isBusy = true;
userService.GetAllRecords(page)
.success(function (data)
{
var results = data;
for (var i = 0; i < results.length; i++)
{
vm.items.push(results[i]);
}
page++;
vm.isBusy = false;
}.bind(vm))
.error(function (error)
{
vm.status = 'Error retrieving data! ' + error.message;
})
.finally(function ()
{
vm.isBusy = false;
});
}
You could load all data once, and append pieces while scrolling:
var vm = this;
var page = 0;
vm.currentItems = [];
var allData = [],
step = 10;
vm.loadData = function ()
{
userService.GetAllRecords(page)
.success(function (data)
{
allData = data;
vm.loadMore(); // Set first 10 items
})
.error(function (error)
{
vm.status = 'Error retrieving data! ' + error.message;
});
}
vm.loadMore = function () {
// Add more items to the currentItems
vm.currentItems = vm.currentItems.concat(allItems.slice(page*step, step));
page++;
}
vm.loadData();
But it depends on what you are trying to achieve why you would want this. If most of the time the users only need to see the first 10 items, then I would recommend to do a http request each time you want to load more. If a user usually scrolls through all the items, then loading all data at once may be what you want.
I've used this module myself in a few applications and this is how you would restrict the call to only running once until your data has been returned.
js code
vm.isBusy = false;
vm.loadMore = function() {
vm.isBusy = true;
userService.GetAllRecords(page).success(function(data) {
var results = data;
for (var i = 0; i < results.length; i++) {
vm.items.push(results[i]);
}
page++;
vm.isBusy = false;
});
}
template code
<div infinite-scroll="loadMore()" infinite-scroll-distance="0" infinite-scroll-disabled="isBusy"></div>
-
This is the code i wrote the last time i used this module.
<div infinite-scroll="loadMoreArticles()" infinite-scroll-distance="0" infinite-scroll-disabled="loadingArticles"></div>
$scope.loadingArticles = false;
$scope.loadMoreArticles = function() {
$scope.loadingArticles = true;
return articlesFactory.getArticles($stateParams.feedType || 'feed', $stateParams.feed, lastArticle.id).then(function(data) {
$scope.articles = _.union($scope.articles, data);
if (data.length > 0) {
$scope.loadingArticles = false;
}
});
};

Resources