AngularFire Unphift项目在AngularJS数组中

时间:2014-08-03 10:07:46

标签: javascript angularjs firebase angularfire

请在推送Firebase RESTful服务时帮助我预先添加项目,当使用ng-repeat显示在DOM中时,新项目应该是最重要的。

//post.js service

 var ref = new Firebase(FIREBASE_URL + 'posts');//creates posts object on root of url
 var posts = $firebase(ref);//we get posts Object from firebase

....

var Post = {

        create: function(post){
            return posts.$add(post);
        }
    .....

//posts.js controller

$scope.submitPost = function(){
    Post.create($scope.post).then(function(){
        console.log('success! post submitted'); 
    });

}

HTML:

<div class="col-xs-12" ng-repeat="(postId, post) in posts">
{{post.title}}
{{post.url}}
</div>

但是在DOM中,最新的项目位于底部,因为我需要新项目应该在顶部。 AngularFire($ firebase)中是否有任何不合时宜的方法?

2 个答案:

答案 0 :(得分:0)

请记住Firebase stores JSON objects, never arrays,它应该是有意义的,它不可能对列表执行非移位操作。 (对按键按字典顺序排序的对象意味着什么?)如果您希望首先显示项目,则需要使用priorities and ordered data。或者,如果列表是简洁的,只需对客户端进行排序。

这是实现非移位的快捷方式,尽管这几乎总是不如使用正确的数据排序或只使用endAt()

app.factory('OrderedList', function($FirebaseArray, $firebase, $firebaseUtils) {
   var OrderedList = $FirebaseArray.$extendFactory({
      unshift: function(data) {
         var self = this, list = this.$list;
         self.$add(data).then(function(ref) {
            var newId = ref.name();
            var pos = self.$indexFor(newId);
            if( pos > 0 ) {
               // place the item first in the list
               list.splice(0, 0, list.splice(pos, 1)[0]);
               // set list priorities to match
               self.reorder();
            }
         });
      },

      // order items by their current index in the list
      reorder: function() {
         var list = this.$list;
         angular.forEach(list, function(rec, i) {
           rec.$priority = i;
           list.$save(rec);
         });
      }
   });

   return function(ref) {
      return $firebase(ref, {arrayFactory: OrderedList}).$asArray();
   }
});

请记住,此特定示例不是并发安全的(如果多个用户同时修改同一列表,则会产生一些不可预测的结果)。实现并发安全解决方案是类似的,但特定于用例(生成优先级的方法将取决于用例)。

答案 1 :(得分:0)

如果您不想设置优先级,一个简单的解决方案是让Firebase自然地订购您的列表,并使用过滤器在客户端进行反转,例如:

angular.module("ReverseFilter",[])
  .filter('reverse', function() {
   function toArray(list) {
    var k, out = [];
    if( list ) {
      if( angular.isArray(list) ) {
        out = list;
      }
      else if( typeof(list) === 'object' ) {
        for (k in list) {
          if (angular.isObject(list[k])) { out.push(list[k]); }
        }
      }
    }
    return out;
  }
  return function(items) {
    return toArray(items).slice().reverse();
  };
});

将此模块相关性添加到您的应用中,您将拥有一个可在ng-repeat属性中使用的过滤器,如下所示:

(ng-repeat="(idx, entry) in journal.months[0] | reverse")