简体   繁体   English

来自二级对象的Firebase $ id

[英]Firebase $id from second level Object

So I have this for example in firebase 所以我在firebase中有这个例子

clients {
   //clients with unique keys {
       invoices: {
         // Invoices with unique Keys
       }
   }
}

I'm returning all this with one ref like so: 我正在用一个ref返回所有这些,如下所示:

.controller('singleClientController', function($scope, $firebaseObject, fbUrl, $routeParams) {

    var id = $routeParams.id;

    var singleRef = new Firebase(fbUrl+'/clients/'+id);
    var client = this;

    client.details = $firebaseObject(singleRef);

})

so in my html, I'm trying to return the $id for both the client and the invoice. 所以在我的HTML中,我试图返回客户端和发票的$id I am able to get the client no problem with {{client.details.$id}} but when I try to do the same thing with the invoice id {{invoice.$id}} I don't get anything. 我可以通过{{client.details.$id}}让客户端没问题但是当我尝试使用发票ID {{invoice.$id}}做同样的事情时,我什么也得不到。

The invoices are displayed through a foreach like so: 发票通过foreach显示如下:

<tr ng-repeat="invoice in client.details.invoices">
     <td>
         <a href="#/invoices/details/{{invoice.$id}}/{{client.details.$id}}">
            {{invoice.settings.number}}
         </a>
     </td>
     ...
</tr>

Is it because the invoices are inside the client? 是因为发票在客户内吗? If so, how would you return the id for the invoices? 如果是这样,您将如何返回发票的ID? It's driving me nuts! 这让我疯了! Please help! 请帮忙!

For a better understanding of my firebase set-up here is a screenshot of what I'm talking about. 为了更好地理解我的firebase设置,这里是我正在谈论的截图。

在此输入图像描述

tl;dr - In Firebase it is ideal to have a flat data structure. tl; dr - 在Firebase中,它是理想的平面数据结构。

JSBin Example JSBin示例

In your case you have invoices nested under clients. 在您的情况下,您有在客户端下嵌套的发票。

{
   "clients": {
      "1": {
         "name": "Alison",
         "invoices": {
            "0001": {
              "amount": 500
              "paid": true
            }
         }
      }
   }
}

This feels natural because the invoices are nicely grouped underneath the proper client. 这种感觉很自然,因为发票很好地分组在适当的客户下面。 However, this can lead to bad performance in syncing data with Firebase. 但是,这可能会导致与Firebase同步数据时性能下降。 Firebase reads all data underneath a node. Firebase会读取节点下的所有数据。

This means every time you read /clients/1 you also get the invoices downloaded over the network. 这意味着每次读取/clients/1您都会收到通过网络下载的发票。 Even if you just need the client's name, you'll also get the the invoices. 即使您只需要客户的名字,您也可以获得发票。

The solution is to flatten your data structure. 解决方案是扁平化您的数据结构。

{
   "clients": {
      "1": {
        "name": "Alison"
      }
   },
   "clientInvoices": {
     "1": {
        "0001": {
          "amount": 500
          "paid": true
        }
     }
   }
}

The important part to grasp here is the shared key . 掌握这里的重要部分是共享密钥

In this example the key is 1 . 在此示例中,键为1 This is for simplicity. 这是为了简单起见。 In reality you'll likely use a .push() id. 实际上你可能会使用.push() id。

By using this pattern you'll still be able to retrieve all of the invoices for the client by simply knowing their key. 通过使用此模式,您仍然可以通过简单地知道其密钥来检索客户端的所有发票。 This also decouples the client from the invoices. 这也使客户与发票分离。

As an added benefit your controller code and ng-repeat will be much easier. 作为额外的好处,您的控制器代码和ng-repeat将更容易。

In your case you should switch from a $firebaseObject to a $firebaseArray for the invoices. 在您的情况下,您应该从$firebaseObject切换到发票的$firebaseArray We can even create a helper factory that gets the invoices by a client's id. 我们甚至可以创建一个帮助工厂,通过客户的ID获取发票。

.factory('invoices', function(fbUrl, $firebaseArray) {
   return function(clientId) {
      var ref = new Firebase(fbUrl).child('clientInvoices').child(clientId);
      return $firebaseArray(ref);
   }
})

// While we're at it, lets create a helper factory for retrieving a
// client by their id
.factory('clients', function(fbUrl, $firebaseObject) {
    return function(clientId) {
       var ref = new Firebase(fbUrl).child('clients').child(clientId);
       return $firebaseObject(ref);
    }
})

Now inject the helper factories into your controller and use the $routeParams.id to retrieve the client's invoices: 现在将辅助工具注入您的控制器并使用$routeParams.id来检索客户端的发票:

.controller('singleClientController', function($scope, $routeParams, invoices, clients) {

    $scope.client = clients($routeParams.id);
    $scope.clientInvoices = invoices($routeParams.id);

})

Now binding it to your template is a breeze: 现在将它绑定到您的模板是一件轻而易举的事:

<tr ng-repeat="invoice in clientInvoices">
     <td>
         <a href="#/invoices/details/{{invoice.$id}}/{{client.$id}}">
            {{invoice.settings.number}}
         </a>
     </td>
     ...
</tr>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM