角度信号和嵌套对象的不可变更新

问题描述 投票:0回答:1

我有两节课:

export class Enrollment {
    private _productId = signal(0);
    private _price = signal(0);
    
    public productId = this._productId.asReadonly();
    public price = this._price.asReadonly();

    public setProductId(productId: number): void {
        this._productId.set(productId);
    }

    public setPrice(price: number): void {
        this._price.set(price);
    }
}

export class Cart {
    private _enrollments = signal<Enrollment[]>([]);
    
    public enrollments = this._enrollments.asReadonly();

    public addToCart(enrollment: Enrollment): void {
        this._enrollments.set([...this._enrollments(), enrollment]);
    }

    public removeFromCart(enrollment: Enrollment): void {
        this._enrollments.set(this._enrollments().filter(e => e !== enrollment));
    }

    public emptyCart(): void {
        this._enrollments.set([]);
    }
}

我正在寻找更新 _enrollments 数组中特定注册中的数据的最佳方法。

我看到有两个选项:

  • 直接改变 Enrollment 对象:我可以在 Enrollment 类中定义一个 equals 函数。这将允许我直接使用公共方法修改注册,这将触发依赖于注册数据更改的任何相关信号。
  • 创建不可变的注册更新:我可以在购物车服务中编写所有注册操作逻辑并使这些方法不可变。这不会直接改变现有的注册情况,但感觉不太理想。

是否有更好的方法来保持不变性并遵守关注点分离原则?

angular signals immutability angular-signals solid
1个回答
0
投票

因为我们要更新数组中的元素

Cart
它应该属于
Cart
类。

export class Enrollment {
  private _productId = signal(0);
  private _price = signal(0);

  public productId = this._productId.asReadonly();
  public price = this._price.asReadonly();

  public setProductId(productId: number): void {
    this._productId.set(productId);
  }

  public setPrice(price: number): void {
    this._price.set(price);
  }
}

export class Cart {
  private _enrollments = signal<Enrollment[]>([]);

  public enrollments = this._enrollments.asReadonly();

  public addToCart(enrollment: Enrollment): void {
    this._enrollments.set([...this._enrollments(), enrollment]);
  }

  public removeFromCart(enrollment: Enrollment): void {
    this._enrollments.set(this._enrollments().filter((e) => e !== enrollment));
  }

  public emptyCart(): void {
    this._enrollments.set([]);
  }

  public updateCartItem(productId: number, newPrice: number) {
    const enrollments = this._enrollments();
    const foundEnrollment: Enrollment | undefined = enrollments.find(
      (item: any) => item.productId === productId
    );
    if (foundEnrollment) {
      if (newPrice !== foundEnrollment.price()) {
        foundEnrollment.setPrice(newPrice);
      }
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.