Listas con deslizamiento (scroll) ilimitado

Alexander A. Ramírez M.

En Ionic es posible cargar datos parcialmente en una lista y si el usuario llega al último elemento es posible cargar más datos y agregarlos a la lista. Esto se logra con la directiva ion-infinite-scroll. Esta permite llamar alguna rutina cada vez que llegamos al final de la lista o estamos cerca de llegar al final.

Ingrese a play.ionic.io para obtener el código para iniciar el tutorial y haga FORK. No olvide hacer FORK.

El objetivo es:

  • Agregar la directiva ion-infinite-scroll después de la directiva ion-list.
  • Crear en el controlador la rutina que va a proveer más datos para la lista. Consiste en agregar 10 elementos más.
  • Hacer broadcast del evento scroll.infiniteScrollComplete para que la lista no siga mostrando el spinner.
  • Especificar mediante la directiva ng-if en la directiva ion-infinite-scroll que función va a indicar si hay mas datos.
  • Crear en el controlador la rutina que indica si hay mas datos.

En el HTML, después la directiva ion-list agregue la directiva ion-infinite-scroll y especifique la rutina que busca y agrega los datos con el atributo on-infinite y la distancia en que se activa la rutina con el atributo distance.

</ion-list>
<ion-infinite-scroll on-infinite="moreData()" distance="10%">
</ion-infinite-scroll>

Ahora vamos a agregar la rutina moreData en el controlador y agreguemos 10 elementos a la lista utilizando el método push de JavaScript.

$scope.moreData = function() {
  var l = $scope.items.length;
  for (var i=l+1; i<=l+10; i++) {
    $scope.items.push({ id: i});
  }
};

Como podemos ver cada vez que se llega al final de la lista se cargan más elementos, pero queda el Spinner dando vueltas. Esto es debido a que no hemos hecho broadcast del evento que indica que ya se cargaron los datos. Esto se hace a través de $scope.$broadcast del evento scroll.infiniteScrollComplete.

$scope.moreData = function() {
  var l = $scope.items.length;
  for (var i=l+1; i<=l+10; i++) {
    $scope.items.push({ id: i});
  }
  $scope.$broadcast('scroll.infiniteScrollComplete');
};

Ahora vamos a explorar otra funcionalidad. Hasta ahora hemos agregado elementos sin límite, pero es posible en muchos casos que se desee limitar la cantidad de elementos o que exista un límite en la cantidad de datos. Para lograr este comportamiento ahora nos valemos de AngularJS y utilizamos la directiva ng-if. Esta permite remover o recrear una porción del DOM (la estructura de elementos de una página) basado en el valor de una expresión (expression). La vamos a colocar en la directiva ion-infinite-scroll y vamos a indicar la rutina que provee dicha información.

<ion-infinite-scroll ng-if="dataAvailable()" on-infinite="moreData()" distance="10%">

Ahora vamos a implementar la rutina dataAvailable en el controlador indicando que no se carguen más de 40 elementos.

$scope.dataAvailable = function() {
  return $scope.items.length<40;
};

Puede verificar el resultado del tutorial si lo desea.