2016-11-27 71 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