Valor_ Valor_ - 9 days ago 10
AngularJS Question

How to change pages based on url

I wan't to be able to change pages based on url. My url's look like this

http://todolist.com/#/1
where last number is page number. So far my pagination is working (angular ui bootstrap). If i try to change page with numbers or buttons in pagination row the pages will change based on response. But url are not changing in url bar and if i change url manually the pages won't change.

This is my controller

controllers.todoCtrl = function ($scope, $timeout, todoFactory, $location, $routeParams) {

if($routeParams.pageNumber == undefined || $routeParams.pageNumber == null){
$scope.currentPage = 1;
} else {
$scope.currentPage = $routeParams.pageNumber;
}
getData();

//get another portions of data on page changed
$scope.pageChanged = function () {
getData();
};

/**
* Get list of todos with pagination
*/
function getData() {
todoFactory.index($scope.currentPage).then(function (data) {
$scope.totalItems = data.paging.count;
$scope.itemsPerPage = data.paging.limit;
$scope.todos = data.Todos;
});
}


My routes

app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/templates/todolists.html',
controller: 'todoCtrl'
}).when('/:pageNumber', {
templateUrl: 'app/templates/todolists.html',
controller: 'todoCtrl'
}).otherwise({ redirectTo: '/'});


What do i have to do to make pagination based on url working. If you need any additional information, please let me know and i will provide. Thank you

Answer

you can use the updateParams function of $route to update the url.

So your code would look like this:

   //get another portions of data on page changed
    $scope.pageChanged = function () {
        //getData();
        $route.updateParams({pageNumber: $scope.currentPage});
    };

This will cause the url to change. However keep in mind that this will destroy and recreate your controller.

Personally I avoid using the build in Angular router and prefer to use UI-Router instead. UI-Router uses a state base approach with a nice clean interface

So in order to use UI-Router you have to grab it from here or install it with your favorite package manager.

Your routes would be configured like this:

var app = angular.module('myApp', ['ui.router']);

app.config(function($stateProvider) {
  $stateProvider.state('home', {
     url: '/',
     templateUrl: 'app/templates/todolists.html',
     controller: 'todoCtrl'
  })
  .state("details", {
     url: '/:pageNumber',
      templateUrl: 'app/templates/todolists.html',
       controller: 'todoCtrl'
   });
});

As you can see in the above sample, states get names with UI-Router. You can use those names later in your controllers and templates to reference the states. In addition to that you can have nested states.

Example in your controller:

controllers.todoCtrl = function ($scope, $timeout, todoFactory, $location, $state, $stateParams) {

    if(!$stateParams.pageNumber){
        $scope.currentPage = 1;
    } else {
        $scope.currentPage = $stateParams.pageNumber; 
    }
    getData();

    //get another portions of data on page changed
    $scope.pageChanged = function () {
        $state.go("details", {pageNumber: $scope.currentPage });
    };

    /**
     * Get list of todos with pagination
     */
    function getData() {
        todoFactory.index($scope.currentPage).then(function (data) {
            $scope.totalItems = data.paging.count;
            $scope.itemsPerPage = data.paging.limit;
            $scope.todos = data.Todos;
        });
    }
Comments