新手求助:AngularJS中Firebase键值对按timestamp排序(orderBy失效)
解决AngularJS + Firebase按Timestamp排序并置顶最新数据的问题
嘿,我看了你的代码,发现几个关键问题导致排序不生效,咱们一步步来修复:
1. 用$asArray()替代$asObject()
Firebase的$asObject()返回的是无序的对象,AngularJS的ng-repeat处理对象时排序逻辑非常受限。要实现有序展示,必须用$asArray()把数据转换成数组:
var ref = new Firebase("https://firebaseio.com/notifications/"); var fb = $firebase(ref.orderByChild('timestamp')); // 先指定按timestamp字段排序 var syncArreglo = fb.$asArray(); // 转换成数组而非对象
2. 修正数据处理的变量引用
你原来的angular.forEach里变量搞混了,应该用遍历到的value和key,而不是syncArreglo.value和syncArreglo.key:
syncArreglo.$loaded().then(function() { angular.forEach(syncArreglo, function (value, key) { if(value != null){ // 直接判断当前遍历的value即可 value.firebaseKey = key; // 把Firebase的键赋值给当前元素的firebaseKey属性 } }); });
3. 两种方式实现最新数据置顶
方式一:Firebase取最新数据 + AngularJS反转顺序
如果你只想展示最新的N条数据,先让Firebase按timestamp升序取最后N条(也就是最新的N条),再用AngularJS反转数组:
// 按timestamp升序排序,取最后5条最新数据 var ref = new Firebase("https://firebaseio.com/notifications/").orderByChild('timestamp').limitToLast(5); var fb = $firebase(ref); var syncArreglo = fb.$asArray();
然后在HTML的ng-repeat里用自定义的reverse过滤器(AngularJS原生没有这个过滤器):
<div ng-repeat="item in syncArreglo | reverse"> {{item.content}} - {{item.timestamp}} </div>
自定义过滤器的代码:
// 在你的AngularJS模块里添加这个过滤器 app.filter('reverse', function() { return function(items) { return items.slice().reverse(); // 复制数组再反转,避免修改原数据 }; });
方式二:存储负时间戳实现原生降序
如果你的timestamp是数字类型(比如Date.now()生成的),可以存入负的时间戳,这样Firebase按timestamp升序排序时,负数更小的(对应原时间戳更大的)会自动排在前面:
存入数据时:
ref.push({ content: "新通知内容", timestamp: -Date.now() // 存储负数时间戳 });
获取数据时直接排序:
var ref = new Firebase("https://firebaseio.com/notifications/").orderByChild('timestamp'); var fb = $firebase(ref); var syncArreglo = fb.$asArray();
HTML里直接展示即可,不需要反转:
<div ng-repeat="item in syncArreglo"> {{item.content}} - {{-item.timestamp}} <!-- 显示时转成正数时间戳 --> </div>
最后提醒
确保你的Firebase每个通知节点都有timestamp字段,否则orderByChild('timestamp')会把没有该字段的节点排在最前面哦~
内容的提问来源于stack exchange,提问作者Vishal Rana
相关产品推荐
相关产品推荐

