2016-11-27 72 views
0

我正在构建一个使用Angular2,Firebase和AngularFire2的实验性应用程序。 这是我的数据是什么样子:我想计算Firebase中的ShoppingCart与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

回答

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

+0

太棒了!我正在开展一个项目,我将需要很多RXJS。感谢你,我相信我可以学到一些东西。再次感谢你。 –

1

由于您使用火力地堡,我注意到的第一件事是关键的名字。像这样修复它们。其中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)); 
} 

现在,做你的最终计算在产品类或订阅。 下面就往里走DisplayCart.component.ts

items; 
constructor(private shoppingCartService: ShoppingCartService){} 

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

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

您仍需要完成你自己的,运气好的话,其余的东西。

+0

你的方法是一种不同的方法。我在列出购物车信息时遇到问题。我的例子在ShoppinCartItem表中有数量信息。产品表还附带价格信息。我想用价格乘以总和。所以我想要找到数据显示的(2 * 5)+(1 * 6)= 16的值。我该怎么做。 –

+0

This [plunker](http://plnkr.co/edit/cWdXRGNk08NDtArDj10O)。你能帮我吗? –

+0

@GökmenSaralu仍然不明白。我说你编写代码的方式非常糟糕。您需要先以正确的方式编写代码,使用上面的代码可以轻松获得对象。 – STEEL