How to implement Infinite Scrolling using Node.js,

2020-07-10 08:18发布

UPDATE 8:

CODE:

<% include ../partials/header %>


<script src="https://www.gstatic.com/firebasejs/3.5.2/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script>

<script>


  var config = {
     info
  };

  firebase.initializeApp(config);

    var fb = firebase.database().ref("posts/fun");

    var app = angular.module('app', ['firebase']);

    app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

        $scope.data = [];
        var _start = 0;
        var _end = 4;
        var _n = 5;

        $scope.getDataset = function() {

            fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {

                $scope.data.push(dataSnapshot.val());
                console.log("THE VALUE:"+$scope.data);

            });

            _start = _start + _n;
            _end = _end + _n;

        };


        $scope.getDataset()

    });

    // Compile the whole <body> with the angular module named "app"
    angular.bootstrap(document.body, ['app']);


</script>


<div class ="containerMarginsIndex">

   <div ng-controller="ctrl">

            <div class="fun" ng-repeat="d in data">
                <h3 class="text-left">{{d.title}}</h3>
                    <div class = "postImgIndex">
                        <a href="details/{{d.id}}" target="_blank">
                            <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" >
                        </a>
                    </div> 
                <div class="postScore">{{d.upvotes - d.downvotes}} HP</div>
            </div>

    </div>

</div>

<% include ../partials/footer %>

SITUATION:

Ok, I have reworked my Firebase database architecture and changed the Firebase rules.

I am now certain the Firebase function returns a value (it is logged in the console).

But I still get the following error:

This HTML:

    <div class="fun" ng-repeat="d in data">
        <h3 class="text-left">{{d.title}}</h3>
            <div class = "postImgIndex">
                <a href="details/{{d.id}}" target="_blank">
                    <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" >
                </a>
            </div> 
        <div class="postScore">{{d.upvotes - d.downvotes}} HP</div>
    </div>

gets REPLACED by this once RENDERED:

<!-- ngRepeat: d in data --> == $0

What have I done wrong ?

3条回答
Evening l夕情丶
2楼-- · 2020-07-10 09:00

You need to include $scope.$apply() because the the scroll event executes outside Angular's context.

Also the event listener should be inside your controller so that the scoped more function is accessible.

Here's an updated fiddle:

https://jsfiddle.net/xue8odfc/2/

I'd say the problem with Angular not resolving the {{post.image}} etc. is due to incompatibilities among the libraries you are referencing. I suggest testing using the versions from the working jsfiddle:

<script src="https://cdn.firebase.com/js/client/2.0.3/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.1/angular.min.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script>
查看更多
太酷不给撩
3楼-- · 2020-07-10 09:07

Add your scroll listener within your controller. The function more does not exist indeed, however you do have a $scope.more method.

app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

    // ORDERED BY TIME:
    var ref = firebase.database().ref("posts/fun");
    var scrollRef = new Firebase.util.Scroll(ref, "time");
    $scope.posts = $firebaseArray(scrollRef);
    scrollRef.scroll.next(5);

    // AS DATA APPEARS IN DATABASE ORDERED BY TIME:
    ref.once('value', function(snap) {
        $scope.rawdata = snap.val();
        $scope.$apply();
    });

    $scope.more = function() {
       scrollRef.scroll.next(5);
    };

    // Add scroll listener
    window.addEventListener('scroll', function() {
      if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
        $scope.$apply($scope.more);
      } 
    });
});

Note that I am calling $scope.more within $scope.$apply so that the scope is digested at the end of the call. Indeed a JS listener on a window scroll event is out of the Angular lifecycle so we need to manually $digest the scope for Angular to update all its watchers and update the HTML. Search online about $scope.$apply if you want to learn more about it.

About your first problem

Your angular application is not started because angular is never initialized. For that you need either to load it synchronously and use the ng-app directive, or if you don't want to change anything with your code you can simply add these lines after your module and controller definition:

// Compile the whole <body> with the angular module named "app"
angular.bootstrap(document.body, ['app']);
查看更多
Evening l夕情丶
4楼-- · 2020-07-10 09:20

It's not displaying in your view because you have nothing on the $scope and you're not using {{}} to interpolate your data. See the following changes:

Assign data to a $scope variable to be used in the view:

$scope.data = [];
var _start = 0;
var _end = 4;
var _n = 5;
var getDataset = function() {
  fb.orderByChild('time').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
  $scope.data.push(dataSnapshot.val());
});

_start = _start + _n;
_end = _end + _n;

And your view, use ngRepeat and {{}} to interpolate:

<div class ="containerMarginsIndex">

          <div class="fun" ng-repeat="d in data">
            <h3 class="text-left">{{d.title}}</h3>
            <div class = "postImgIndex">
            <a href="details/{{post.id}}" target="_blank">
                <img class= "imgIndex" src="/images/uploads/{{post.image}}" >
            </a>
            </div> 
            <div class="postScore">({{d.upvotes - d.downvotes}}) HP</div>
        </div>

</div>
查看更多
登录 后发表回答