Jonathan Thurft
Jonathan Thurft

Reputation: 4173

How to detect an "on scroll" event using angularJs & Ionic Framework

I come from a JQuery background and don't know if this is possible or not in AngularJS.

I am working on a project using Ionic framework & AngularJS

I am trying to capture the "on scrolling" event using angular.

Currently I use the following HTML to create a list of 20 items and the following code outputs the "test" string on the console log on page load. But when I scroll up or down the list the event doesn't seem to fire again.

I've been researching but I can't seem to come across a way to get the "on scroll event" after the page has been loaded. At least directive doesn't get call when the user is interacting with the list, so I think this is the wrong approach.

How can I capture that event in angular? Is it possible?

HTML

<ion-content>
      <div class="list" >
        <div class="item" ng-repeat="item in data.items" when-scrolled="loadMore()" >Item {{item}}</div>
      </div>
      </ion-content>

JS

angular.module('starter.controllers', ["ionic"])
.controller('AppCtrl', function($scope,$ionicScrollDelegate) {

  $scope.myTitle = 'Template';

  $scope.data = {
    items : [],
    title : ''
  };

  for(var i = 0; i < 20; i++) {
    $scope.data.items.push(i);
  }
})
.directive('whenScrolled', function () {
    return function(scope, element, attrs) {
        console.log("test");
    };
});

Upvotes: 1

Views: 13118

Answers (4)

Code Spy
Code Spy

Reputation: 9964

we can use on-scroll or on-scroll-complete events on content then we need to call a function in the controller like below

<ion-view view-title="Wall">
    <ion-content **on-scroll-complete="checkScroll()"**>
        <div class="list" ng-repeat="w in data.wallList">
        </div>
    </ion-content>
</ion-view>

Complete tutorial is given here http://freakyjolly.com/detect-ionic-view-page-bottom-load-infinite-data/

Upvotes: 0

LeftyX
LeftyX

Reputation: 35597

Is there any particular reason why you are creating your own directive ? Ionic already has scroll events if you want to load more data.
In those situation the best thing to do is to switch to collection-repeat.

collection-repeat allows an app to show huge lists of items much more performantly than ng-repeat.

It renders into the DOM only as many items as are currently visible.

This means that on a phone screen that can fit eight items, only the eight items matching the current scroll position will be rendered.

You can change your HTML using the new directive:

Item {{item}}

and add:

<ion-infinite-scroll ng-if="!theEnd" on-infinite="loadMore()" distance="50%"></ion-infinite-scroll>

before the closing tag of your content </ion-content>.

The directive will be in charge to fetch the data for you.

I am suggesting to use collection-repeat but the same principle can be applied to ng-repeat as well. The first one is just faster when it deal with lot of data.

Your controller should look something like this:

$scope.loadMore = function(argument) {
        page++;
        dataService.GetData(page, pageSize)
          .then(function(result) {
            console.log('items fetched: ' + result.data.length);
            if (result.data.length > 0) {
                angular.forEach(result.data, function(value, key) {
                  $scope.data.items.push(value);
                });
            }
            else {
                $scope.theEnd = true;
            }
        })
        .finally(function() {
            $scope.$broadcast("scroll.infiniteScrollComplete");
        });
 };

You have to remember to broadcast the event scroll.infiniteScrollComplete at the end of your fetch process.

You can read more on this topic here.

Or play with this sample here.

Upvotes: 1

Jonathan Thurft
Jonathan Thurft

Reputation: 4173

This is what worked
I had to change the markup and the directives to work on Ionic library

http://codepen.io/anon/pen/WQOGZy

<ion-scroll direction="y" on-scroll="gotScrolled(this)" delegate-handle="homeScroll">
        <p>Stuff 1</p>
        <p>Stuff 2</p>
        <p>Stuff 3</p>
        <p>Stuff 4</p>
        <p>Stuff 5</p>
        <p>Stuff 6</p>
        <p>Stuff 7</p>
        <p>Stuff 8</p>
        <p>Stuff 9</p>
        <p>Stuff 10</p>
      </ion-scroll>

Upvotes: 1

Akshay Kumar
Akshay Kumar

Reputation: 576

You can define the directive as,

app.directive('ngScroll', function() {
return {
    restrict: 'A',
    scope: false,
    link: function(scope, element, attrs) {
        element.bind("onscroll", function(event) {
            scope.$apply(attrs.ngScroll);
        });
    }
  };
});

And html as,

<div class="item" ng-repeat="item in data.items" ng-scroll="loadMore()" >Item {{item}}</div>
  </div>

Upvotes: 0

Related Questions