【问题标题】:How can I delete result of list query in one step?如何一步删除列表查询的结果?
【发布时间】:2017-03-25 21:54:03
【问题描述】:

我已尝试删除 operations,其中产品 ID 等于 myProdID。 它删除了整个操作分支,而不仅仅是等于查询结果的分支。

this.af.database.list('operations', {
        query: {
          orderByChild: 'products/productID',
          equalTo: myProdID
        }
      }).remove();

我应该使用什么来在一行代码中完成它而不是运行 for 循环来删除每个项目? .map ?

【问题讨论】:

    标签: angular firebase firebase-realtime-database rxjs angularfire2


    【解决方案1】:

    您可以像这样执行单个更新:

    ref.update({
      '/operations/products/foo': null,
      '/operations/products/bar': null
    });
    

    这将从ref/operations/products 中批量删除 foo 和 bar 孩子,同时保持所有其他孩子不受影响。

    但我想你仍然需要做一些循环来确定要更新的路径。

    【讨论】:

      【解决方案2】:

      这不仅仅是一行代码,但你可以这样做:

      deleteOperations(productID: any): Observable<any> {
      
        return this.af.database.list('operations', {
          query: {
            orderByChild: 'products/productID',
            equalTo: productID
          }
        })
      
        // AngularFire2 list/object observables don't complete - they re-emit if
        // the database changes - so use the first operator to ensure it completes
        // and ignores subsequent database changes.
      
        .first()
      
        // Use Array.prototype.reduce to create an object containing the keys to
        // be removed and use the FirebaseObjectObservable's update method to
        // remove them.
      
        .mergeMap((ops) => this.af.database.object('operations').update(
          ops.reduce((acc, op) => { acc[op.$key] = null; return acc; }, {})
        ));
      }
      

      上面的函数会返回一个 observable 并且删除会在调用者订阅它时执行。

      如果你希望函数返回一个承诺,你可以这样做:

      deleteOperations(productID: any): Promise<any> {
      
        return this.af.database.list('operations', {
          query: {
            orderByChild: 'products/productID',
            equalTo: productID
          }
        })
      
        // AngularFire2 list/object observables don't complete - they re-emit if
        // the database changes - so use the first operator to ensure it completes
        // and ignores subsequent database changes.
      
        .first()
      
        // Convert the observable to a promise when that will resolve when the
        // observable completes.
      
        .toPromise()
      
        // Use Array.prototype.reduce to create an object containing the keys to
        // be removed and use the FirebaseObjectObservable's update method to
        // remove them.
      
        .then((ops) => this.af.database.object('operations').update(
          ops.reduce((acc, op) => { acc[op.$key] = null; return acc; }, {})
        ));
      }
      

      【讨论】:

      • 它没有用。我查看了更多有关 mergeMap 的信息,[gist.github.com/btroncone/d6cf141d6f2c00dc6b35#mergemap](RxJS 5 Operators By Example) 有一个示例,但我看不出与您的不同。
      • mergeMap 用于在 update 返回的 promise 解析完成时完成 observable。在什么情况下它不起作用?
      • 对不起,我订阅的时候就这样了。我对 RxJS 的东西不是很好。有什么方法可以返回一个承诺。我打算把它放在一个服务函数中,所以当它被调用时,它会返回一个承诺,并在调用组件时得到解决。
      • 或者我可以返回 Observable mergeMap 返回并在我猜的组件中订阅它。
      • 等等,你是说我不必订阅它?好吧,除非我订阅,否则它不会从 Firebase 中删除这些节点(没有解决更新承诺)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 2019-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      相关资源
      最近更新 更多