如何用单个save方法实现Observable中商品的新增与更新?
问题:用单一save方法实现商品创建与更新
我目前已能获取商品数据、渲染表单并正确填充字段值。不想分别使用create和update两个方法,希望仅通过一个save方法完成操作。我正尝试基于product$ observable判断当前是处理已有商品还是创建新商品。
现有代码如下:
// product.component.ts public product$ = this.productService.product$; ngOnInit(): void { this.product$.pipe(tap((product) => console.log('product', product))).subscribe((product) => { this.form = new FormGroup({ name: new FormControl(product?.name, [ Validators.required, ]), description: new FormControl(product?.description, [ Validators.required, ]), }); }); } ... // 预期目标 save(form: FormGroup): void { if (form.invalid) { return; } if(product$) { this.productService.update(...); } else { this.productService.create(...); } }
我知道可以再次订阅product$,但觉得应该已获取所需值。另外,创建商品时URL为example.com/products,更新时URL始终为example.com/products/123,我曾尝试通过路由参数判断,但不知如何正确实现。请问如何通过检查productId等信息实现仅用save方法?
解决方案
方法一:维护当前商品实例
在组件中保存订阅product$时拿到的商品对象,直接通过该对象的id判断是创建还是更新,无需重复订阅。
// product.component.ts import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { ProductService } from './product.service'; import { tap } from 'rxjs/operators'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent implements OnInit { public product$ = this.productService.product$; private currentProduct: any; // 建议替换为你的Product类型定义 form!: FormGroup; constructor(private productService: ProductService) {} ngOnInit(): void { this.product$.pipe( tap((product) => console.log('product', product)) ).subscribe((product) => { this.currentProduct = product; this.form = new FormGroup({ name: new FormControl(product?.name, [Validators.required]), description: new FormControl(product?.description, [Validators.required]), }); }); } save(form: FormGroup): void { if (form.invalid) { return; } const formData = form.value; // 判断当前商品是否存在id(已有商品) if (this.currentProduct?.id) { this.productService.update(this.currentProduct.id, formData).subscribe({ next: () => { /* 处理更新成功逻辑,比如提示、跳转 */ }, error: (err) => { /* 处理更新错误 */ } }); } else { this.productService.create(formData).subscribe({ next: () => { /* 处理创建成功逻辑 */ }, error: (err) => { /* 处理创建错误 */ } }); } } }
方法二:通过路由参数判断
结合你的URL规则(创建无id,更新带id),利用ActivatedRoute获取路由参数中的id,直接判断操作类型。
// product.component.ts import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { ProductService } from './product.service'; import { ActivatedRoute } from '@angular/router'; import { tap } from 'rxjs/operators'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent implements OnInit { public product$ = this.productService.product$; private productId: string | null = null; form!: FormGroup; constructor( private productService: ProductService, private route: ActivatedRoute ) {} ngOnInit(): void { // 获取路由中的商品id参数 this.productId = this.route.snapshot.paramMap.get('id'); this.product$.pipe( tap((product) => console.log('product', product)) ).subscribe((product) => { this.form = new FormGroup({ name: new FormControl(product?.name, [Validators.required]), description: new FormControl(product?.description, [Validators.required]), }); }); } save(form: FormGroup): void { if (form.invalid) { return; } const formData = form.value; if (this.productId) { this.productService.update(this.productId, formData).subscribe({ next: () => { /* 处理更新成功 */ }, error: (err) => { /* 处理更新错误 */ } }); } else { this.productService.create(formData).subscribe({ next: () => { /* 处理创建成功 */ }, error: (err) => { /* 处理创建错误 */ } }); } } }
可选优化:双重判断(更稳妥)
如果想避免单一判断的误差,可以同时结合商品实例和路由参数:
save(form: FormGroup): void { if (form.invalid) return; const formData = form.value; const isUpdate = this.productId || (this.currentProduct?.id); if (isUpdate) { const id = this.productId || this.currentProduct.id; this.productService.update(id, formData).subscribe(/* ... */); } else { this.productService.create(formData).subscribe(/* ... */); } }
内容的提问来源于stack exchange,提问作者Damon
相关产品推荐
相关产品推荐

