Smart-Table icon indicating copy to clipboard operation
Smart-Table copied to clipboard

st-persist, st-src-safe, and maintaining state for pagination

Open mg1075 opened this issue 9 years ago • 8 comments

Is there a working example of using the st-persist directive and st-src-safe where maintaining state works for pagination?

Sorting works (though not nicely, since you can't seem to initialize sort declaratively) and input search works, but it seems the pagination always reverts back to a "start" of 0.

mg1075 avatar Feb 27 '16 10:02 mg1075

Just two days ago i had the same issue !! thanks to Laurent R, I followed the example of stPersist directive: http://plnkr.co/edit/ekwiNt?p=preview

  1. you watch the table state and persist it somewhere (service, localstorage, session,etc) whenever it changes.
  2. When the table is restored you read the value from your storage and call the slice function of the table controller ...
    And Then i had that issue : When you use WATCH for the whole table, That blocks other WATCH from smarttable and then you lost pagination**(always reverts back to a "start" of 0.)**; to resolve that you have yo use a specific WATCH on an attribute that changes value when you are In/Out of table and that works perfectly for me.

example : instead of using scope.$watch(function(){...},true); you have to use scope.$watch('specificAttribute', function(value) {...},true);

aliasoft avatar Mar 21 '16 15:03 aliasoft

Hi. in case of st-pipe and st-persist:

  1. call to st-persist directive.
  2. call to st-pipe callback 2 times !!

the first time it call st-pipe with the right tableState. the second, the tableState has start to zero.

why it's called 2 times. checking:

the second pipe() is called inside stSort and magicly it's found why the start is zeroed.

this.sortBy = function sortBy (predicate, reverse) {
      tableState.sort.predicate = predicate;
      tableState.sort.reverse = reverse === true;

      if (ng.isFunction(predicate)) {
        tableState.sort.functionName = predicate.name;
      } else {
        delete tableState.sort.functionName;
      }

      tableState.pagination.start = 0;
      return this.pipe();
    };

regards.

dg14 avatar Apr 13 '16 12:04 dg14

Workaround: directive:

            // fetch the table state when the directive is loaded
            if (localStorage.getItem(nameSpace)) {
                var savedState = JSON.parse(localStorage.getItem(nameSpace));
                var tableState = ctrl.tableState();

                angular.extend(tableState, savedState);
                tableState.pagination.start2 = tableState.pagination.start;
                ctrl.pipe();

            }

controller:

$scope.callServer = function(tableState) {
            if ($scope.isLoading)
                return;
            $scope.isLoading = true;

            var start = tableState.pagination.start2 || tableState.pagination.start;
            if (tableState.pagination.start != start) {
                tableState.pagination.start = start;
            }

dg14 avatar Apr 13 '16 12:04 dg14

Faced the same issue. The workaround from dg14 works for me but very hacky :(

sharonx avatar Jul 07 '16 20:07 sharonx

+1, this is a really ugly hack

nvurgaft avatar Sep 25 '16 14:09 nvurgaft

Here's another ugly hack based on dg14's that moves the logic into the st-persist directive. I needed this because I wasn't using st-pipe/callServer(tableState) to load the data and I didn't see an easy way to access tableState from the parent controller.

//save the table state every time it changes
scope.$watch(function () {
    return ctrl.tableState();
}, function (newValue, oldValue) {

    if (newValue.pagination.start2) {
	    if (newValue.pagination.start2 < newValue.pagination.totalItemCount) {
		// consume start2
		newValue.pagination.start = newValue.pagination.start2;
		newValue.pagination.start2 = undefined;
		ctrl.pipe();
	    }
    }

    if (newValue !== oldValue) {
	localStorage.setItem(nameSpace, JSON.stringify(newValue));
    }
}, true);

//fetch the table state when the directive is loaded
if (localStorage.getItem(nameSpace)) {
    var savedState = JSON.parse(localStorage.getItem(nameSpace));
    var tableState = ctrl.tableState();

    angular.extend(tableState, savedState);
    tableState.pagination.start2 = tableState.pagination.start;
    ctrl.pipe();
}

mathewguest avatar Apr 29 '17 18:04 mathewguest

I've changed the data set so that it returns asynchronously and with the plunker that is provided above and it works. However, that uses an old version (v1.2.6) of smart table and after updating smart table to use v2.1.10, the pagination no longer persists. It get's overridden.

The only thing that I've changed in the plunker is that now it's using $timeout to wait a few milliseconds before populating the $collection. I've also added st-safe-src on the table as an attribute.

Plunker with updated code and v2.1.10 smart table: http://plnkr.co/edit/W5q4VkOuNJL2nPZ3JxPZ?p=preview

Plunker with updated code and v1.2.6 of smart table: http://plnkr.co/edit/frmoC3nsQNn0mhmNE8Sx?p=preview

YussufElarif avatar Aug 28 '18 13:08 YussufElarif

Another ugly hack - wait to restore the old state before it gets overridden.

` //fetch the table state when the directive is loaded if (localStorage.getItem(nameSpace)) { var savedState = JSON.parse(localStorage.getItem(nameSpace));

                $timeout(() => {
                    var tableState = ctrl.tableState();
                    angular.extend(tableState, savedState);
                    ctrl.pipe();
                }, 400);
            }`

yellowds avatar Sep 12 '18 13:09 yellowds