Как правильно упорядочить данные в хронологическом порядке в бесконечном прокрутке Firebase?
CODE:
<script>
var app = angular.module('app', ['firebase']);
app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {
console.log(<%=lastID%>);
$scope.data = [];
var _n = Math.ceil(($(window).height() - 50) / (350)) + 1;
var _start = <%= lastID %>;
var _end = <%= lastID %> + _n - 1;
$scope.getDataset = function() {
fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
$scope.data.push(dataSnapshot.val());
$scope.$apply()
console.log("THE VALUE:"+$scope.data);
});
_start = _start + _n;
_end = _end + _n;
};
$scope.getDataset();
window.addEventListener('scroll', function() {
if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
$scope.$apply($scope.getDataset());
}
});
});
// Compile the whole <body> with the angular module named "app"
angular.bootstrap(document.body, ['app']);
</script>
СИТУАЦИЯ:
lastID - это идентификатор последнего созданного сообщения. Они идут назад (от -1 до lastID).
Это решение работает отлично, за исключением случаев, когда некоторые сообщения удаляются.
(Сообщения упорядочены от самых последних до самых старых (от lastID до -1)).
Например, если есть 16 сообщений, lastID = -16.
Если я удаляю сообщения от -13 до -5 и post -3, lastID остается на -16.
Это означает, что когда страница загружается, сообщения не появляются после того, как загружаются 3 первых сообщения (от -16 до -14), и мне нужно прокручивать их несколько раз, чтобы появился пост -4.
Вопрос:
Как я могу убедиться, что если некоторые сообщения будут удалены, мой Infinite Scroll script пропустит идентификаторы существующих сообщений и просто загрузит 3 ближайших сообщения?
ЧТО Я ПРОВЕРЯЛ:
Я посмотрел на это:
Показать сообщения в порядке убывания
Но я не уверен, как реализовать эти решения внутри моего бесконечного прокрутки. Любые идеи?
Ответы
Ответ 1
Если я правильно понял вас, вам не нужно использовать конец. Этого можно достичь, используя startAt + limit
fb.orderByChild('id').startAt(_start).limit(n)...
И используйте макет для упорядочивания предметов по убыванию. Используя это, вам не нужно беспокоиться о последовательности идентификаторов, если они последовательны
UPDATE
Вы можете сделать это еще проще. Просто обновите свое начало с помощью последнего значения
fb.orderByChild('id').startAt(_start).limit(_n).on("child_added", function(dataSnapshot) {
$scope.data.push(dataSnapshot.val());
$scope.$apply()
_start = dataSnapshot.child('id').val()
console.log("THE VALUE:"+$scope.data);
});
В этом случае ваш _start
всегда будет содержать последний идентификатор, и вы можете не беспокоиться об удаленных элементах.
В качестве альтернативы вы можете использовать временную переменную для хранения последнего значения id и использовать ее в startAt
Ответ 2
В основном все данные, сохраненные в Firebase, упорядочены в хронологическом порядке, поскольку автоматически созданный идентификатор для каждой записи основан на отметке времени. Следовательно, вам не нужно заказывать свои значения. Просто убедитесь, что вы добавляете новый идентификатор в пару значений ключа, которая сохраняется в Firebase.
Если вы хотите изменить порядок списка (чтобы самые последние записи отображались вверху), вам нужно будет отменить список после его прочтения.
ИЗМЕНИТЬ
Если вы хотите получить позицию своей записи в базе данных, вы можете использовать что-то похожее на следующее:
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByKey().on("child_added", function(snapshot) {
console.log(snapshot.key() + " was " + snapshot.val().height + " meters tall");
});
Дополнительную информацию о заказе здесь.
Ответ 3
startAt
и limitToFirst
можно использовать для получения следующих сообщений.
Просто сообщите, что firebase начнется после id
последнего загруженного сообщения (start + 1
в этом случае), и удаленный id
будет пропущен автоматически.
var itemsPerScroll = 1;
$scope.getDataset = function() {
var start = $scope.data.slice(-1)[0].id
fb.orderByChild('id').startAt(start + 1).limitToFirst(itemsPerScroll)
.on("child_added", function(dataSnapshot) {
$scope.data.push(dataSnapshot.val());
$scope.$apply()
})
}