You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:00:53