我想用Angularfire2计算Firebase中ShoppingCart的总和

时间:2016-11-27 20:46:36

标签: javascript angular firebase 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

2 个答案:

答案 0 :(得分:1)

由于您使用的是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课程。放在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));
}

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

items;
constructor(private shoppingCartService: ShoppingCartService){}

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

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

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

答案 1 :(得分:1)

问题在于此代码:

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