无法使用Angularfire 0.8为$ asObject()的子键设置优先级 [英] Cannot set priority on $asObject()'s child keys using Angularfire 0.8

查看:131
本文介绍了无法使用Angularfire 0.8为$ asObject()的子键设置优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据Angularfire文档,当使用通过 $ asObject()返回的对象时,可以通过定义一个 $ priority 对象的属性,然后使用 $ save()



我的代码很好用,但是 $ priority 没有任何作用。这里有一些代码在评论中有完整的解释:

$ p $ app.factory('MyService',function($ rootScope,$ firebase) {

//完整的Firebase url
var ref = * obfuscated *;

//将数据集作为包含对象的对象返回
var data = $ firebase(ref)。$ asObject;

//这个对象是MyService返回的内容
var Data = {

//创建一个新的方法数据集中的对象
// keyed by myId尝试通过$ priority设置
//记录的优先级returnData.uid是一个有效的字符串
create:function(returnData ,myId){
data [myId] = {
myId:myId,
$ priority:returnData.uid
};

//不需要()函数(){
setMyId(myId); $(
$ data)
// $ rootScope监听器之间的内容。 b $ b});
} ,
findByMyId:function(myId){
if(myId){
return data [myId];
}
}
};

函数setMyId(myId){
$ rootScope.myId = User.findByMyId(myId);


//这个事件侦听器工作正常,在用户登录时触发
//并返回数据
$ rootScope。$ on('$ firebaseSimpleLogin:login' ,函数(e,returnData){

// returnData.uid有正确的值 - 这个
//函数应该返回带有
// a的对象(又名记录)优先级匹配returnData.uid
var query = $ firebase(ref.startAt(returnData.uid).endAt(returnData.uid))。$ asObject();

// console ($ firebase(ref)。$ asObject()),它返回$ b $(
//属性,但没有记录)所有记录的优先级仍然是
// null。
console.log(query);

query。$ loaded(function( ){
setData(query.myId);
});
});

返回数据;
});

是的,我正在关注Thinkster.io的教程,我在第7章。并不是关于这个章节的其他问题的重复,我已经找到了解决方案,在他们的例子中,我们已经找到了前Angularfire 0.8代码的方法,只是不能设置$优先级,到目前为止我花了大约5个小时一个解决方案,通过我自己的努力,并在网上。

任何接管人?

解决方案 $ asObject()方法旨在存储键/值对,以及不作为集合使用的单数记录,这开始有所帮助。



在内部,同步对象的 $保存方法调用Firebase的 setWithPriority 。在 set setWithPriority 调用中,子节点被替换。任何元数据,如这些孩子的优先级被取代。

在AngularFire中, $ asArray 用于处理有序集合,并且提供了在子节点上设置 $ priority 的能力(当然,因为它将子节点视为不是自己集合的单数记录) / p>

因为在你的情况下,你想使用固定键而不是推入标识符,你可能想用$ extendFactory来重写$ add方法,如下所示:
$ b $ pre $ angular.module(MY_APP).factory('FixedKeysFactory',function($ FirebaseArray,$ firebaseUtils){
return $ FirebaseArray。$ extendFactory({
$ add:function(data){
this._assertNotDestroyed('$ add');
if(angular.isObject(data)& amp; ;& typeof data。$ id ==='string'){
return this。$ inst()。$ set(data。$ id,$ firebaseUtils.toJSON(data));
}
else {
返回这个。$ inst()。$ push($ firebaseUtils.toJSON(data));
}
}
});
});

然后,您可以将此代码传递到您的$ firebase实例中,以代替默认工厂:

  var list = $ firebase(ref,{arrayFactory:FixedKeysFactory})。$ asArray(); 

一个简单但少awesomatic™解决方案将手动添加您的对象到数组,手动给他们一个$ id,然后调用$ save:

  var list = $ firebase(ref)。$ asArray(); 
var i = list.length;
list.push({foo:'bar',$ id:'kato'});
list。$ save(i);

有关未来的一些说明:将很快有可能使用任何字段作为排序标准,不需要设置优先级(耶!)。在使用AngularFire的同步数组调用$ add之前,可能会设置自己的$ id,只要我使用其他开发人员(如0.8.3版本)清除它即可。


According to the Angularfire docs, when working with an object returned through $asObject(), you can set priority for said object by defining a $priority property on the object and then using $save().

My code works great, but $priority isn't doing anything. Here's some code with complete explanations in the comments:

app.factory('MyService', function($rootScope, $firebase) {

  // The complete Firebase url
  var ref = *obfuscated*;

  // Returning the dataset as an object containing objects
  var data = $firebase(ref).$asObject;

  // This object is what's returned by MyService
  var Data = {

    // Method to create a new object within the data set,
    // keyed by myId. Attempting to set priority for the
    // record via $priority. returnData.uid is a valid string.
    create: function(returnData, myId) {
      data[myId] = {
        myId: myId,
        $priority: returnData.uid
      };

      // No need to explain the stuff between here and the
      // $rootScope listener below, just added for context
      data.$save().then(function() {
        setMyId(myId);
      });
    },
    findByMyId: function(myId) {
      if (myId) {
        return data[myId];
      }
    }
  };

  function setMyId(myId) {
    $rootScope.myId = User.findByMyId(myId);
  }

  // This event listener works fine, fires
  // at user login and returns data
  $rootScope.$on('$firebaseSimpleLogin:login', function(e, returnData) {

    // returnData.uid has the correct value - this
    // function should return the object(aka record) with
    // a priority matching returnData.uid
    var query = $firebase(ref.startAt(returnData.uid).endAt(returnData.uid)).$asObject();

    // console shows an object with the normal $firebase
    // properties, but no records. If I define query without
    // limiting the set ($firebase(ref).$asObject()), it returns
    // the full set just fine. The priority on all records is still
    // null.
    console.log(query);    

    query.$loaded(function() {
      setData(query.myId);
    });
  });

  return Data;
});

Yes, I'm following Thinkster.io's tutorial and I'm in Chapter 7. No, this is not a duplicate of the other questions about that chapter, I already found my way around the pre-Angularfire 0.8 code present in their examples, just can't set $priority, and I've spent about 5 hours so far trying to find a solution through my own efforts and on the web.

Any takers?

解决方案

When viewed in the light of how JavaScript works with objects (i.e. unordered), how JSON handles objects (i.e. unordered), and in light of the expectation that AngularFire's $asObject() method is intended for storing key/value pairs, and singular records that are not used as a collection, this starts to make some sense.

Internally, the synchronize'd object's $save method calls Firebase's setWithPriority. In set or setWithPriority calls, the child nodes are replaced. Any meta data like priorities on those children are replaced.

In AngularFire, $asArray is intended to handle ordered collections, and provides the ability to set $priority on child nodes (only one level deep, of course, as it treats its children as singular records that are not themselves collections).

Since, in your case, you want to work with fixed keys rather than push ids, you'll probably want to override the $add method using $extendFactory and do something like the following:

angular.module(MY_APP).factory('FixedKeysFactory', function($FirebaseArray, $firebaseUtils) {
  return $FirebaseArray.$extendFactory({
    $add: function(data) {
      this._assertNotDestroyed('$add');
      if( angular.isObject(data) && typeof data.$id === 'string' ) {
        return this.$inst().$set(data.$id, $firebaseUtils.toJSON(data));
      }
      else {
        return this.$inst().$push($firebaseUtils.toJSON(data));
      }
    }
  });
});

You could then pass this into your $firebase instance in place of the default factory:

var list = $firebase(ref, {arrayFactory: FixedKeysFactory}).$asArray();

A simpler but less awesomatic™ solution would be to manually add your objects to the array, manually giving them a $id, then call $save:

var list = $firebase(ref).$asArray();
var i = list.length;
list.push({ foo: 'bar', $id: 'kato' });
list.$save(i);

Some notes on the future: It will soon be possible to use any field as sort criteria and there will be no need to set priorities (yay!). It will probably be possible to set your own $id before calling $add on a synchronized array in AngularFire as soon as I clear that with the other devs (like the 0.8.3 release).

这篇关于无法使用Angularfire 0.8为$ asObject()的子键设置优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆