如何通过参数ID从MongoDB获取单个产品及Angular前端调用
Angular组件调用单个产品API的解决方案
我已经实现了从MongoDB获取全部产品的功能,但点击产品时无法通过URL参数中的ID获取单个产品详情。后端API和前端服务方法已更新,但不知道如何在Angular组件中调用该方法,请求帮助。
后端API(API.js)
router.route('/products').get(function (req, res) { db.collection('products').find().toArray(function (err, results) { if (err) return console.log(err); console.log(results); res.send(results); }); }); router.route('/products/:_id').get(function (req, res) { db.collection('products').findOne({"_id":ObjectId(req.params._id)},(err,results)=>{ res.send(results); }) })
前端产品服务(Product service.ts)
getOneProduct(_id: string): Observable<any> { return this.http.get<any>(`${this.url}/${_id}`); }
待修改的产品组件(product-component.ts)
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { CartService } from '../cart.service'; import { FavService } from '../fav.service'; import { products } from '../models/products'; import { ProductsService } from '../products.service'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent implements OnInit { // products!: products; productsList:any=[]; id: string = ''; private sub: any; constructor(private activatedRoute: ActivatedRoute, private productService: ProductsService, private cartService:CartService, private router:Router, private favService: FavService) { } ngOnInit(): void { } activeTab:string = 'Delivery'; onTabClick(tab: string){ this.activeTab = tab; } }
解决方案
1. 获取URL参数并调用服务方法
修改组件的ngOnInit方法,通过ActivatedRoute提取URL中的_id参数,再调用产品服务的getOneProduct方法获取详情:
ngOnInit(): void { // 订阅路由参数变化 this.sub = this.activatedRoute.params.subscribe(params => { this.id = params['_id']; // 确保路由配置的参数名和后端一致 // 调用服务获取单个产品 this.productService.getOneProduct(this.id).subscribe({ next: (product) => { this.productsList = product; // 赋值给组件变量,用于模板渲染 }, error: (err) => { console.error('获取产品详情失败:', err); } }); }); }
2. 清理订阅避免内存泄漏
添加ngOnDestroy钩子,在组件销毁时取消参数订阅:
// 先导入OnDestroy接口 import { Component, OnInit, OnDestroy } from '@angular/core'; // 实现OnDestroy接口 export class ProductComponent implements OnInit, OnDestroy { // ... 其他代码保持不变 ngOnDestroy(): void { if (this.sub) { this.sub.unsubscribe(); } } }
3. 确认路由配置正确
确保路由模块中已定义带参数的产品详情路由:
// 路由模块示例 const routes: Routes = [ // ... 其他路由 { path: 'product/:_id', component: ProductComponent } ];
4. 可选:用async管道简化订阅(推荐)
如果不想手动管理订阅,可使用async管道自动处理订阅和取消:
import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; export class ProductComponent implements OnInit { product$!: Observable<any>; constructor(private activatedRoute: ActivatedRoute, private productService: ProductsService) {} ngOnInit(): void { this.product$ = this.activatedRoute.params.pipe( switchMap(params => { return this.productService.getOneProduct(params['_id']); }) ); } }
模板中使用async管道渲染:
<div *ngIf="product$ | async as product"> <h2>{{product.name}}</h2> <p>{{product.description}}</p> <!-- 其他产品字段 --> </div>
内容的提问来源于stack exchange,提问作者user19571598
相关产品推荐
相关产品推荐

