2017-07-03 40 views
0

我使用firebase在我的web應用中實現了無限滾動。Firebase:如何在沒有類似評分的帖子跳過的情況下加載頂級帖子?

在我的「頂部」部分,我展示了用戶的最高優先級帖子。

問題是,在我目前的實現中,幾個帖子被跳過。

也就是說,如果很多帖子有相同的分數,有些將不會出現。

我明白爲什麼發生這種情況,我通過很多12的加載我的職位,然後做這個選擇下一批:

start = childDataSnapshot.child("inversedScore").val() + 1; 

這種方法的問題是,如果有超過12具有相同投票分數的元素,或者如果存在具有相同投票分數的兩個元素,一個是數字12,另一個數字是13,那麼數字13被忽略,並且我們直接進入下一個分數級別。

例如,這裏是我的服務器上的數據:

post1: score: 15 
post2: score: 14 
post3: score: 13 
post4: score: 12 
post5: score: 11 
post6: score: 10 
post7: score: 10 
post8: score: 9 
post9: score: 9 
post10: score: 9 
post11: score: 8 
post12: score: 7 

//posts 13 and 14 will be ignored 
post13: score: 7 
post14: score: 7 

post15: score: 6 
post16: score: 6 

這裏是什麼,我會看到在客戶端上:

post1: score: 15 
post2: score: 14 
post3: score: 13 
post4: score: 12 
post5: score: 11 
post6: score: 10 
post7: score: 10 
post8: score: 9 
post9: score: 9 
post10: score: 9 
post11: score: 8 
post12: score: 7 
post15: score: 6 
post16: score: 6 

什麼其他的辦法是那裏裝載有頂帖firebase,以便相同分數的頂端帖子從不「跳過」?


客戶端:

var started = false; 

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

    if(started == false) { 
     started = true; 

     $scope.bricks = []; 
     var _n = 12; 

     if ($(window).width() < 992) { 
      _n = 2; 
     } 

     var firstElementsLoaded = false; 
     var _start = -1000000000; 
     var position = 0; 

     $scope.getDataset = function() { 
      var sendObject = { 
       start: _start, 
       section: section, 
       n: _n, 
      } 
      $.ajax({ 
       type: "POST", 
       url: "images/top", 
       data: sendObject, 
      }).done(function(result) { 
       for (var i = 0; i < result.array.length; i++) { 
        console.log("result: "+result.array[i]); 
        $scope.bricks.push(result.array[i]); 
        $scope.$apply(); 
       } 

       _start = result.start; 
       firstElementsLoaded = true; 
      }); 
     }; 


     $scope.getDataset(); 

     var screenHeight; 
     var existingScreenHeight 

     if ($(window).width() < 992) { 
      screenHeight = (_n + 1) * 350; 
      existingScreenHeight = -350; 
     } 
     else { 
      screenHeight = 1 * Math.ceil($(window).height()); 
      existingScreenHeight = -screenHeight; 
     } 

     window.addEventListener('scroll', function() { 

      if (firstElementsLoaded == true) { 
       if (window.scrollY >= ((screenHeight) + existingScreenHeight)) { 
        existingScreenHeight += (screenHeight); 
        $scope.$apply($scope.getDataset()); 
        firstElementsLoaded = false; 
       } 
      } 
     }); 
    } 
}); 

angular.bootstrap(document.body, ['app']); 

服務器:

router.post('/images/top', function(req, res, next) { 
    var start = parseInt(req.body.start); 
    var section = req.body.section; 
    var n = parseInt(req.body.n); 
    var returnArray = []; 
    var screenshotRef = admin.database().ref("posts/"+section); 
    screenshotRef.orderByChild("inversedScore").startAt(start).limitToFirst(n).once("value", function(dataSnapshot) { 

     dataSnapshot.forEach(function(childDataSnapshot) { 

      start = childDataSnapshot.child("inversedScore").val() + 1; 

      var post = childDataSnapshot.val(); 

      var file = bucket.file(post.image); 

      var config = { 
       action: 'read', 
       expires: Date.now() + global.expiryTime, 
      }; 

      file.getSignedUrl(config, function(err, url) { 
       if (err) { 
        console.error(err); 
        return; 
       } 
       post.image = url; 
       returnArray.push(post); 
       if (returnArray.length == n) { 
        var returnObject = { 
         start: start, 
         array: returnArray 
        } 
        res.send(returnObject); 
       } 
      }); 
     }); 
    }); 
}); 

回答

0

最簡單的方法,直接刪除+ 1

start = childDataSnapshot.child("inversedScore").val(); 

這會導致一些數據的重新檢索,因爲如果您已經抓取了7的一半,那麼您將最終再次抓取下一個負載以及其餘的7 s。


在大規模這不會是完全有效的,但它是最簡單的選擇...我唯一能想到的。

您現在可以使用Firebase功能來創建單獨的節點(因爲數據便宜),並在添加子節點時對所有帖子進行排序,然後僅用數字獲取下一行(不按任何鍵排序)。

+1

您可以輕鬆地跳過客戶端中的額外項目(通常稱爲錨項目)。您不能在查詢中跳過它。如果您將錨項的鍵作爲第二個參數傳入,則可以確保只有一個重疊項。 –

+0

你能鏈接到@FrankvanPuffelen上的文檔嗎?有趣的,從來沒有見過它。 – theblindprophet

+0

請參閱https://stackoverflow.com/questions/43376331/firebase-query-order-by-and-start-at-name/43376894,https://stackoverflow.com/questions/41278544/how-to-paging- query-from-firebase-using-android-firebaseui/41285470#41285470,https://stackoverflow.com/questions/40721803/firebase-range-query。如果您對此有任何疑問,請告知我,因爲它絕對不是API中最直觀的部分。 –

相關問題