Angular2连接Firebase:如何获取复杂订单对象的所有参数?
解决Angular+Firebase订单详情页无法获取数据的问题
我看了你的代码和描述,问题主要出在订单详情页的数据获取逻辑错误以及模板渲染的变量/字段不匹配上,下面一步步帮你修复:
1. 核心问题:你在详情页获取了用户的所有订单,而不是单个订单
你的order$当前是用户的所有订单数组(来自getOrdersByUser),但模板里把它当成了单个订单对象来用,这就导致order.datePlaced这类属性找不到,页面自然空白。
因为你是点击「查看订单」按钮进入详情页,所以正确的逻辑应该是:
- 通过路由传递订单ID
- 根据订单ID获取单个订单数据
步骤1:添加路由参数(传递订单ID)
假设你的路由配置里,订单详情页的路径是/orders/:orderId,点击「查看订单」按钮时,跳转到该路径并带上订单ID:
<!-- 在订单列表页的按钮上添加跳转 --> <button [routerLink]="['/orders', order.key]">查看订单</button>
步骤2:在OrderService中添加获取单个订单的方法
现在你的服务只有获取订单列表的方法,需要新增获取单个订单的方法:
// order.service.ts getOrderById(orderId: string) { return this.db.object(`/orders/${orderId}`).valueChanges(); }
valueChanges()会返回单个订单的可观察对象,而不是数组。
步骤3:修改OrderDetailsComponent的逻辑,获取单个订单
现在组件需要从路由中获取orderId,然后调用新的服务方法:
// order-details.component.ts import { ActivatedRoute } from '@angular/router'; import { switchMap } from 'rxjs/operators'; import { Subscription } from 'rxjs'; export class OrderDetailsComponent implements OnInit, OnDestroy { order$; private subscriptions = new Subscription(); // 用一个集合管理所有订阅,更方便 constructor( private orderService: OrderService, private authService: AuthService, private route: ActivatedRoute // 注入路由服务 ) {} ngOnInit() { // 从路由获取orderId,再获取对应订单 this.order$ = this.route.paramMap.pipe( switchMap(params => { const orderId = params.get('orderId'); return this.orderService.getOrderById(orderId); }) ); } ngOnDestroy() { this.subscriptions.unsubscribe(); } }
这里不需要再订阅用户信息,因为订单数据里已经包含userId(你在下单时应该已经存入了),详情页只需要根据订单ID获取数据即可。
2. 修复模板中的字段和变量错误
你的模板里有几个明显的错误,导致即使拿到数据也无法正确渲染:
- 变量名重复:
*ngFor="let order of order.shipping"里的order和外层的order冲突了 - 字段不匹配:你的数据库里是
items,但模板里用了shipping;而且没有处理items下的子对象和product信息
修改后的模板应该这样写:
<!-- order-details.component.html --> <div class="card" *ngIf="order$ | async as order"> <div class="card-body"> <h5 class="card-title">你的订单</h5> <p class="card-text">下单时间:{{ order.datePlaced | date:'yyyy-MM-dd HH:mm' }}</p> <ul class="list-group list-group-flush"> <!-- 遍历订单里的items --> <li *ngFor="let item of order.items" class="list-group-item"> <!-- 展示product的信息 --> <img [src]="item.product.imageUrl" alt="{{ item.product.title }}" style="width: 50px; margin-right: 10px;"> <span>{{ item.product.title }} × {{ item.quantity }}</span> <div class="float-right"> {{ item.totalPrice | currency:'USD':'symbol' }} </div> </li> <!-- 订单总价 --> <li class="list-group-item font-weight-bold"> 订单总价 <div class="float-right"> {{ order.totalPrice | currency:'USD':'symbol' }} <!-- 假设你的订单根节点有totalPrice字段 --> </div> </li> </ul> </div> </div>
注意:如果你的订单根节点没有totalPrice,可以通过遍历items计算,或者下单时就把总价存入订单根节点(推荐后者,避免前端重复计算)。
3. 额外检查:确认订单数据结构是否正确
确保你在下单时,订单数据的结构和你预期的一致,比如:
// 下单时的order对象示例 const order = { userId: '用户UID', datePlaced: new Date().toISOString(), totalPrice: 100, // 订单总价 items: [ { quantity: 2, totalPrice: 50, product: { imageUrl: 'xxx.jpg', price: 25, title: '商品名称' } } ] };
如果数据结构不对,即使代码正确也无法渲染。
这样修改后,你应该就能正常获取并展示订单的详细信息了!
内容的提问来源于stack exchange,提问作者Lebek
相关产品推荐
相关产品推荐

