我想用 Angularfire2 计算 Firebase 的 ShoppingCart 总和

I want to calculate the sum of the ShoppingCart at Firebase with Angularfire2

我正在构建一个使用 Angular2、Firebase 和 AngularFire2 的实验性应用程序。 这是我的数据的样子:

{
  "ShoppingCartItem":
      {
        "item1":{
            "quantity": 2,
            "productId": "abc"
        },
        "item2":{
            "quantity": 1,
            "productId": "bcd"
        }
      }
  "Product"
      {
        "abc":{
            "name": "product1",
            "price": 5
    },
        "bcd":{
            "name": "product2",
            "price": 6
        }
    }
}

下面是我的cart.ts

this.items = this.af.database.list('ShoppingCartItem')
          .map(carts => {
            return carts.map(item => {
              item.product = this.af.database.object(`Product/${item.productId}`);
              return item;
            });
          });

下面是我的cart.html

<table>
<tbody>
    <tr *ngFor="let item of (items | async)">
        <td>{{(item.product | async)?.name}}</td>
        <td><input type="text" name="quantity" [(ngModel)]="item.quantity" size="1" class="form-control"></td>
        <td>{{(item.product | async)?.price | number: '.2'}}</td>
        <td>{{(item.product | async)?.price * item.quantity | number: '.2'}}</td>
    </tr>
</tbody>
<tfoot>
    <tr>
      <td colspan="2" class="text-right">
        <strong>Total :</strong>
      </td>
      <td colspan="2" class="text-left">
        ?????????
      </td>
    </tr>
</tfoot>

我想计算 ShoppingCart 的总和。所以我想找到数据显示的 (2*5) + (1*6) = 16 的值。我该怎么做。

这个plunker

由于您使用的是 Firebase,我首先注意到的是键名。像这样修复它们。其中 cart.$key 是一些哈希码,例如-KXeML1Na9qCsvK4JSyQ.

{
  "ShoppingCartItem": {
    -KXeML1OkDyUVTAdHYPx : {
      -KXeML1OkDyUVTAdHYPx: true,
      -KXeML1PP4faQG2Z3fzU: true
    },
    -KXeML1Na9qCsvK4JSyQ: {
      -KXeML1PP4faQG2Z3fzU: true
    }
  },
  "Products": {
    -KXeML1OkDyUVTAdHYPx:{
      "name": "product1",
      "price": 5
    },
    -KXeML1PP4faQG2Z3fzU:{
      "name": "product2",
      "price": 6
    }
  }
}

现在重写你的前端逻辑。也请写出合适的Product class。放在下面里面 shoppingcart.service.ts

findProductKeysForCart(cartId: string): Observable<string[]> {
 return this.database.list('ShoppingCartItem', {
    query: {
      orderByKey: true,
      equalTo: cartId
    }
  })
    //.do(console.log)// Check whats coming,
    //.map(result => result[0])// might be needed
    .map(sci => sci.map(product => product.$key));
}

findProductsForProductKeys(productKeys$: Observable<string[]>): Observable<Product[]> {
  return productKeys$
    .map(productKeys => productKeys.map(productKey => this.database.object(`Products/${productKey}`)))
    .flatMap(prodObservables => Observable.combineLatest(prodObservables));
}


findAllProductsForCart(cartId): Observable<Product[]> {
    //this fn gets your Products for a cart
    return this.findProductsForProductKeys(this.findProductKeysForCart(cartId));
}

现在,在产品 class 或订阅中进行最终计算。 下面将进入 DisplayCart.component.ts

items;
constructor(private shoppingCartService: ShoppingCartService){}

ngOnInit(){
  const items$ = this.shoppingCartService.findAllProductsForCart(this.cartId);

 items$.subscribe(items => this.items = items);
}

你还需要自己完成剩下的东西,祝你好运。

问题出在这段代码中:

carts.map(cart => {
    this.af.database.object(`Product/${cart.productId}`)
    .subscribe(d => {
        cart.product = d;
    });
  return cart;
});
carts.forEach(cartItem => {
    qty += cartItem.quantity;
    total += cartItem.quantity * cartItem.product.price;
    // console.log(cartItem);
});

两个调用:carts.mapcarts.forEach 是同步的并且一个接一个地发生。但是产品加载(通过 af.database.object)是异步的,因此当您遍历尚未加载的 cartItem 产品时。

解决方案是链接产品加载和总计算。参见 here