Javascript 来自第二级对象的Firebase$id

Javascript 来自第二级对象的Firebase$id,javascript,angularjs,firebase,angularfire,Javascript,Angularjs,Firebase,Angularfire,例如,我在firebase中有这样一个例子 clients { //clients with unique keys { invoices: { // Invoices with unique Keys } } } 我用一个参考号返回所有这些,如下所示: .controller('singleClientController', function($scope, $firebaseObject, fbUrl, $routeParams)

例如,我在firebase中有这样一个例子

clients {
   //clients with unique keys {
       invoices: {
         // Invoices with unique Keys
       }
   }
}
我用一个参考号返回所有这些,如下所示:

.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);

})
<tr ng-repeat="invoice in client.details.invoices">
     <td>
         <a href="#/invoices/details/{{invoice.$id}}/{{client.details.$id}}">
            {{invoice.settings.number}}
         </a>
     </td>
     ...
</tr>
因此,在我的html中,我试图返回客户机和发票的
$id
。我能够获取客户机,但当我尝试对发票id执行相同操作时,
{{client.details.$id}}
没有任何问题

发票通过foreach显示,如下所示:

.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);

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

...
是因为发票在客户体内吗?如果是,您将如何返回发票的id?它快把我逼疯了!请帮忙

为了更好地了解我的firebase设置,这里是我所说内容的屏幕截图


tl;dr-在Firebase中,理想的做法是采用平面数据结构

在您的案例中,发票嵌套在客户机下

{
   "clients": {
      "1": {
         "name": "Alison",
         "invoices": {
            "0001": {
              "amount": 500
              "paid": true
            }
         }
      }
   }
}
这感觉很自然,因为发票很好地分组在适当的客户机下面。但是,这可能会导致与Firebase同步数据时性能不佳。Firebase读取节点下的所有数据

这意味着您每次阅读
/clients/1
时,也会通过网络下载发票。即使你只需要客户的名字,你也会得到发票

解决方案是扁平化数据结构。

{
   "clients": {
      "1": {
        "name": "Alison"
      }
   },
   "clientInvoices": {
     "1": {
        "0001": {
          "amount": 500
          "paid": true
        }
     }
   }
}
这里需要掌握的重要部分是共享键

在本例中,键为
1
。这是为了简单。实际上,您可能会使用
.push()
id

通过使用此模式,您仍然能够通过简单地了解客户机的密钥来检索所有发票。这还将客户机与发票分离

作为一个额外的好处,您的控制器代码和
ng repeat
将更加容易

在您的情况下,发票应从
$firebaseObject
切换到
$firebaseArray
。我们甚至可以创建一个助手工厂,通过客户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);
    }
})
现在将助手工厂注入控制器,并使用
$routeParams.id
检索客户的发票:

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

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

})
现在,将其绑定到模板很容易:

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

...

由于嵌套发票列表是一个键/值对,因此id只是散列中每个项目的键。也。