Angularfire:如何通过其中一个属性访问项目?

Posted

技术标签:

【中文标题】Angularfire:如何通过其中一个属性访问项目?【英文标题】:Angularfire: How to access an item by one of it's properties? 【发布时间】:2014-10-17 20:27:26 【问题描述】:

我的 Firebase 数据是这样组织的:

+ myappname
  + customers
    + -JV2NQv3GmoM81zdUfTe
      + name: "Mary"
      + age: "24"
      + ...
    + -JV2N9NnItCfz5vB04RS
      + name: "John"
      + age: "32"
      + ...
    + ...
  + ...

如何通过姓名检索客户? 该名称保证是唯一的。 这是我的客户服务,目前:

app.factory('Customer', function ($firebase, FIREBASE_URL) 
  var ref = new Firebase(FIREBASE_URL + 'customers');
  var customers = $firebase(ref);

  var Customer = 
    all: customers,
    create: function (customer) 
      return customers.$add(customer).then(function (ref) 
        var customerId = ref.name();
        return customerId;
      );
    ,
    set: function(customerId, customer) 
      return customers.$child(customerId).$set(customer);
    ,
    find: function (customerId) 
      return customers.$child(customerId);
    ,
    findByName: function (customerName)  // TODO...
    ,
    delete: function (customerId) 
      var customer = Customer.find(customerId);
      customer.deleted = true;
      customer.$on('loaded', function () 
        customers.$child(customerId).$set(customer);
      );
    
  ;
  return Customer;
);

我是否应该在每次 findByName() 调用时扫描所有客户? 还是我应该建立类似“二级索引”的东西? 请给点建议,我才刚刚开始... :-(

【问题讨论】:

Get users by name property using Firebase的可能重复 尽管您才刚刚开始,但您已经列出了两个可能的解决方案。 Firebase 允许您按节点名称或其优先级搜索节点。如果您还没有将优先级用于其他任何事情,您可以将名称设置为优先级并使用Query.startAtQuery.endAt 按名称进行选择。如果您已经为其他事情使用了优先级,您确实可以创建一个单独的索引,仅用于将用户名映射到节点名。 @Kato:你说得对,我的问题几乎与其他问题完全相同......对不起,我在提问之前没有找到它...... 【参考方案1】:

感谢 Kato 的指示和 Frank van Puffelen 的建议,我终于解决了自己的问题。 我确实在我的 Firebase 中添加了一个“索引”、“customersByName”(记住“磁盘空间很便宜,用户的时间不是”Firebase 座右铭... :-)。 我没有遵循参考答案中的方向,因为我认为这个解决方案更通用:它可以扩展到多个“索引”... 我想在这里发布它,希望它对其他人有用。 我想看看 cmets:这个解决方案有可能的缺点吗?总体而言,对于某些用例,这是一个可取的解决方案吗?

app.factory('Customer', function ($firebase, FIREBASE_URL) 
  var ref = new Firebase(FIREBASE_URL + 'customers');
  var customers = $firebase(ref);
  var refByName = new Firebase(FIREBASE_URL + 'customersByName');
  var customersByName = $firebase(refByName);

  var Customer = 
    all: customers,
    create: function (customer) 
      return customers.$add(customer).then(function (ref) 
        var customerId = ref.name();
        customersByName.$child(customer.name).$set(customerId);
        return customerId;
      );
    ,
    set: function(customerId, customer) 
      var oldname = customers.$child(customerId).name;
      if (customer.name !== oldname) 
        customersByName.$remove(oldname);
      
      customersByName.$child(customer.name).$set(customerId);
      return customers.$child(customerId).$set(customer);
    ,
    find: function (customerId) 
      return customers.$child(customerId);
    ,
    findByName: function (customerName) 
      return customersByName.$child(customerName);
    ,
    delete: function (customerId) 
      var customer = Customer.find(customerId);
      customer.deleted = true;
      customer.$on('loaded', function () 
        customersByName.$remove(customer.name);
        customers.$child(customerId).$set(customer);
      );
    
  ;

  return Customer;
);

【讨论】:

以上是关于Angularfire:如何通过其中一个属性访问项目?的主要内容,如果未能解决你的问题,请参考以下文章

用户已登录但无法通过 AngularFire 访问 Firebase 存储

使用 angularfire2 时如何访问本机 Firebase 对象?

使用 angularFire 隐式同步在 ng-repeat 中访问 Firebase 唯一 ID

如何在 AngularFire2 中获取当前用户的访问令牌?

使用 AngularFire2 (Angular2 rc.5) 访问 firebase.storage()

通过视图中的相对 :id 访问属性