使用AngularFire v2获取关键值有点清晰?

时间:2013-12-15 17:37:04

标签: firebase angularfire

很抱歉这个很长,但这让我有点疯狂:

假设我想在加载时获得一个项目的“标题”和“.priority”键值。

首先让我们看看每件事情的构成方式:

 $scope.items = $firebase(new Firebase("https://****.firebaseio.com"));

 $scope.items.$on('loaded', function() { 

console.log($scope.items);

});

我们得到:

> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
    > $add: function (item, cb) {
    > $bind: function (scope, name) {
    > $child: function (key) {
    > $getIndex: function () {
    > $on: function (type, callback) {
    > $remove: function (key) {
    > $save: function (key) {
    > $set: function (newValue) {

    > this is my item: Object
          $$hashKey: "012"
          $id: "this is my item"
          $priority: 2884707
          title: "this is the title of my item"
          __proto__: Object


    > __proto__: Object

看起来不错,让我们尝试抓住优先级:

 console.log($scope.items.$child('$priority'));

糟糕:

Uncaught Error: Firebase.child failed: First argument was an invalid path: "$priority". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"

很好,我们暂时不会跳过这个,只是尝试标题:

console.log($scope.items.$child('title'));

> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
    > $add: function (item, cb) {
    > $bind: function (scope, name) {
    > $child: function (key) {
    > $getIndex: function () {
    > $on: function (type, callback) {
    > $remove: function (key) {
    > $save: function (key) {
    > $set: function (newValue) {
    > __proto__: Object

没有标题。

好的,让我们以不同的方式尝试:

    var firstItem = $scope.items.$getIndex()[0];  //returns $ids in order of priority
     console.log($scope.items.$child(firstItem));

     > Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
         > $add: function (item, cb) {
         > $bind: function (scope, name) {
         > $child: function (key) {
         > $getIndex: function () {
         > $on: function (type, callback) {
         > $remove: function (key) {
         > $save: function (key) {
         > $set: function (newValue) {
              title: "this is the title of my item"
         > __proto__: Object

但现在没有优先权!

厨房水槽在计算机时间发誓:

 console.log($scope.items.title);

     > undefined

 console.log($scope.items[0].title);

     > Uncaught TypeError: Cannot read property 'title' of undefined 

  console.log(Object.keys($scope.items));     

     > ["$bind", "$add", "$save", "$set", "$remove", "$child", "$on", "$getIndex"]

我错过了什么?我可以设法通过做几次掉头来获得'头衔',(弄清楚项目的$ id是使用'$ getIndex()',抓住第n个项目,然后使用'$ child()'再次打电话),但即便如此也不适合优先考虑。是否有更简单的方法从AngularFire v2中获取关键值?或者以任何方式获得$优先权?

3 个答案:

答案 0 :(得分:5)

我相信我/正在经历同样的问题。希望这与您的经历有关。即:

$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com"));
$scope.items.$on('loaded', function() {
  console.log($scope.items['some key']); // this writes undefined to console
});

我注意到,如果我不依赖loaded事件,这实际上确实有效。例如,HTML:

<a href="#" data-ng-click="logItem()">click me</a>

并在JS中:

$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com"));
$scope.logItem = function() {
  console.log($scope.items['some key']); // this works
}

单击“单击我”链接会按预期将我的项目记录到控制台。

感觉像loaded时间的集合没有完全填充来自firebase的基础项目。

答案 1 :(得分:4)

$child方法只应用于创建 AngularFire参考。致电$child与致电$firebase(new Firebase(parentULR + "/childName"))相同。在您的示例中,如果您要做的只是获取给定对象的$prioritytitle,则可以执行以下操作:

$scope.items = $firebase(new Firebase("https://****.firebaseio.com"));
$scope.items.$on('loaded', function() {
  var item = $scope.items['your-item-id'];
  console.log(item['$priority']);
  console.log(item.title);
});

如果您不知道项目的ID,可以迭代$scope.items对象以查找它。

答案 2 :(得分:3)

正如您所指出的那样,您的示例有点碎片化,并且也没有可用的数据结构示例。因此,要了解您想要实现的目标,有点难以理解。我将在下面对所有这些事情做出一些假设,然后相应地提供一个工作示例。如果这不能回答这个问题,也许它会帮助我们深入挖掘并找到您正在寻找的确切用例。

首先让我们假设我们在kato.firebaseio.com/users上有一个用户列表,每个用户都是这样的对象:

/users/:id/name
/users/:id/email
/users/:id/favorite_dessert

现在,让我们假设我想使用以下angularCode进行这些工作:

<ul>
  <li ng-repeat="user in users">{{user.name}} really likes {{user.favorite_dessert}}</li>
</ul>

在我的控制器中,我可以放这样的东西:

var fbRef = new Firebase('https://kato.firebaseio.com/users');
$scope.users = $firebase( fbRef );

现在,它们将自动显示在我的HTML代码中。

现在,我们假设当单击其中一个用户时,我想获得双向绑定,可以使用以下格式进行编辑:

<form ng-controller="EditUserController">
      <input ng-model="user.name" type="text" />
      <input ng-model="user.email" type="text" />
      <input ng-model="user.favorite_dessert" type="text" />
</form>

EditUserController内,我可以按如下方式获取用户:

var fbRef = new Firebase('https://kato.firebaseio.com/users/'+user_id);
$firebase( fbRef ).$bind($scope, 'user');

或者我可以像这样使用$child(纯粹是为了演示$ child的使用,不是必需的):

var fbRef = new Firebase('https://kato.firebaseio.com/users');
// $child gives a new $firebase object! not a ref to a hash key!
$firebase( fbRef ).$child( user_id ).$bind($scope, 'user');

如果我想在控制器内以编程方式访问任何此类数据,我可以这样做:

var fbRef = new Firebase('https://kato.firebaseio.com/users');
var usersRef = $firebase( fbRef );
var userId = 'kato';
usersRef.$on('loaded', function() {
   if( usersRef.hasOwnProperty(userId) ) {
      // note that we just grab it by key; not $child!
      var userRecord = usersRef[userId]; 
      console.log(userId + ' was found, name is ' + userRecord.name + ' and priority is ' + userRecord['$priority']);
   }

});