如何使用新的 Firebase (2016) 实现无限滚动?
How to implement Infinite Scrolling with the new Firebase (2016)?
问题:
如何使用 javascript(和 node.js)在 Firebase 中实现高效的无限滚动?
我检查了什么:
问题:较旧的 firebase ^
Infinite scroll with AngularJs and Firebase
代码来自:
Infinite scroll with AngularJs and Firebase
“首先,我建议在您的 Firebase 中创建一个索引。为了回答这个问题,我创建了这个索引:
{
"rules": {
".read": true,
".write": false,
"messages": {
".indexOn": "id"
}
}
}
然后,让我们用 Firebase 创造一些奇迹:
// @fb: your Firebase.
// @data: messages, users, products... the dataset you want to do something with.
// @_start: min ID where you want to start fetching your data.
// @_end: max ID where you want to start fetching your data.
// @_n: Step size. In other words, how much data you want to fetch from Firebase.
var fb = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/');
var data = [];
var _start = 0;
var _end = 9;
var _n = 10;
var getDataset = function() {
fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
data.push(dataSnapshot.val());
});
_start = _start + _n;
_end = _end + _n;
}
最后,更好的无限滚动(没有 jQuery):
window.addEventListener('scroll', function() {
if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
getDataset();
}
});
我在 React 中使用这种方法,无论您的数据有多大,它都非常快。"
(2015 年 10 月 26 日在 15:02 回答)
(作者:乔布萨缪尔)
问题
在该解决方案中,每次滚动到达屏幕高度的末端时都会加载 n 个帖子。
根据屏幕尺寸,这意味着在某些时候会加载比需要多得多的帖子(屏幕高度只包含 2 个帖子,这意味着每次我们到达结尾时都会加载比需要多 3 个帖子)例如 n = 5 时的屏幕高度)。
这意味着每次我们到达 scrollheight 的末尾时,3*NumberOfTimesScrollHeightHasBeenPassed
将加载比需要更多的帖子。
我当前的代码(一次加载所有帖子,无无限滚动):
var express = require("express");
var router = express.Router();
var firebase = require("firebase");
router.get('/index', function(req, res, next) {
var pageRef = firebase.database().ref("posts/page");
pageRef.once('value', function(snapshot){
var page = [];
global.page_name = "page";
snapshot.forEach(function(childSnapshot){
var key = childSnapshot.key;
var childData = childSnapshot.val();
page.push({
id: key,
title: childData.title,
image: childData.image
});
});
res.render('page/index',{page: page});
});
});
这里是无限分页的完整代码。
函数createPromiseCallback
同时支持promise和回调。
function createPromiseCallback() {
var cb;
var promise = new Promise(function (resolve, reject) {
cb = function (err, data) {
if (err) return reject(err);
return resolve(data);
};
});
cb.promise = promise;
return cb;
}
函数getPaginatedFeed
实现实际分页
function getPaginatedFeed(endpoint, pageSize, earliestEntryId, cb) {
cb = cb || createPromiseCallback();
var ref = database.ref(endpoint);
if (earliestEntryId) {
ref = ref.orderByKey().endAt(earliestEntryId);
}
ref.limitToLast(pageSize + 1).once('value').then(data => {
var entries = data.val() || {};
var nextPage = null;
const entryIds = Object.keys(entries);
if (entryIds.length > pageSize) {
delete entries[entryIds[0]];
const nextPageStartingId = entryIds.shift();
nextPage = function (cb) {
return getPaginatedFeed(endpoint, pageSize, nextPageStartingId, cb);
};
}
var res = { entries: entries, nextPage: nextPage };
cb(null, res);
});
return cb.promise;
}
下面是如何使用 getPaginatedFeed
函数
var endpoint = '/posts';
var pageSize = 2;
var nextPage = null;
var dataChunk = null;
getPaginatedFeed(endpoint, pageSize).then(function (data) {
dataChunk = data.entries;
nextPage = data.nextPage;
//if nexPage is null means there are no more pages left
if (!nextPage) return;
//Getting second page
nextPage().then(function (secondpageData) {
dataChunk = data.entries;
nextPage = data.nextPage;
//Getting third page
if (!nextPage) return;
nextPage().then(function (secondpageData) {
dataChunk = data.entries;
nextPage = data.nextPage;
//You can call as long as your nextPage is not null, which means as long as you have data left
});
});
});
关于要在屏幕上放置多少项目的问题,你可以给出这样的解决方案,对于每个 post 给出固定的 x 高度,如果需要更多 space 则放置 "read more" link 在 post 的底部,当用户点击时会显示缺失的部分。在这种情况下,您可以在屏幕上保持固定数量的项目。此外,您可以检查屏幕分辨率以放置更多或更少的项目。
问题:
如何使用 javascript(和 node.js)在 Firebase 中实现高效的无限滚动?
我检查了什么:
问题:较旧的 firebase ^
Infinite scroll with AngularJs and Firebase
代码来自: Infinite scroll with AngularJs and Firebase
“首先,我建议在您的 Firebase 中创建一个索引。为了回答这个问题,我创建了这个索引:
{
"rules": {
".read": true,
".write": false,
"messages": {
".indexOn": "id"
}
}
}
然后,让我们用 Firebase 创造一些奇迹:
// @fb: your Firebase.
// @data: messages, users, products... the dataset you want to do something with.
// @_start: min ID where you want to start fetching your data.
// @_end: max ID where you want to start fetching your data.
// @_n: Step size. In other words, how much data you want to fetch from Firebase.
var fb = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/');
var data = [];
var _start = 0;
var _end = 9;
var _n = 10;
var getDataset = function() {
fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
data.push(dataSnapshot.val());
});
_start = _start + _n;
_end = _end + _n;
}
最后,更好的无限滚动(没有 jQuery):
window.addEventListener('scroll', function() {
if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
getDataset();
}
});
我在 React 中使用这种方法,无论您的数据有多大,它都非常快。"
(2015 年 10 月 26 日在 15:02 回答)
(作者:乔布萨缪尔)
问题
在该解决方案中,每次滚动到达屏幕高度的末端时都会加载 n 个帖子。
根据屏幕尺寸,这意味着在某些时候会加载比需要多得多的帖子(屏幕高度只包含 2 个帖子,这意味着每次我们到达结尾时都会加载比需要多 3 个帖子)例如 n = 5 时的屏幕高度)。
这意味着每次我们到达 scrollheight 的末尾时,3*NumberOfTimesScrollHeightHasBeenPassed
将加载比需要更多的帖子。
我当前的代码(一次加载所有帖子,无无限滚动):
var express = require("express");
var router = express.Router();
var firebase = require("firebase");
router.get('/index', function(req, res, next) {
var pageRef = firebase.database().ref("posts/page");
pageRef.once('value', function(snapshot){
var page = [];
global.page_name = "page";
snapshot.forEach(function(childSnapshot){
var key = childSnapshot.key;
var childData = childSnapshot.val();
page.push({
id: key,
title: childData.title,
image: childData.image
});
});
res.render('page/index',{page: page});
});
});
这里是无限分页的完整代码。
函数createPromiseCallback
同时支持promise和回调。
function createPromiseCallback() {
var cb;
var promise = new Promise(function (resolve, reject) {
cb = function (err, data) {
if (err) return reject(err);
return resolve(data);
};
});
cb.promise = promise;
return cb;
}
函数getPaginatedFeed
实现实际分页
function getPaginatedFeed(endpoint, pageSize, earliestEntryId, cb) {
cb = cb || createPromiseCallback();
var ref = database.ref(endpoint);
if (earliestEntryId) {
ref = ref.orderByKey().endAt(earliestEntryId);
}
ref.limitToLast(pageSize + 1).once('value').then(data => {
var entries = data.val() || {};
var nextPage = null;
const entryIds = Object.keys(entries);
if (entryIds.length > pageSize) {
delete entries[entryIds[0]];
const nextPageStartingId = entryIds.shift();
nextPage = function (cb) {
return getPaginatedFeed(endpoint, pageSize, nextPageStartingId, cb);
};
}
var res = { entries: entries, nextPage: nextPage };
cb(null, res);
});
return cb.promise;
}
下面是如何使用 getPaginatedFeed
函数
var endpoint = '/posts';
var pageSize = 2;
var nextPage = null;
var dataChunk = null;
getPaginatedFeed(endpoint, pageSize).then(function (data) {
dataChunk = data.entries;
nextPage = data.nextPage;
//if nexPage is null means there are no more pages left
if (!nextPage) return;
//Getting second page
nextPage().then(function (secondpageData) {
dataChunk = data.entries;
nextPage = data.nextPage;
//Getting third page
if (!nextPage) return;
nextPage().then(function (secondpageData) {
dataChunk = data.entries;
nextPage = data.nextPage;
//You can call as long as your nextPage is not null, which means as long as you have data left
});
});
});
关于要在屏幕上放置多少项目的问题,你可以给出这样的解决方案,对于每个 post 给出固定的 x 高度,如果需要更多 space 则放置 "read more" link 在 post 的底部,当用户点击时会显示缺失的部分。在这种情况下,您可以在屏幕上保持固定数量的项目。此外,您可以检查屏幕分辨率以放置更多或更少的项目。