BehaivorSubject不保留数组和重复项

时间:2019-01-12 01:12:10

标签: angular behaviorsubject

我有一个服务和一个组件,当我添加一个值时,它会保留在数组中,但是当我添加其他值时,我的第一个值会将值更改为第二个

服务

 export class PrepayService {
  private _carts: BehaviorSubject<ShoppingCart[]>; 
  carts : Observable<ShoppingCart[]>
  dataStore :{
    carts: ShoppingCart[]
  };
  constructor() { 
    this.dataStore = { carts: []};
    this._carts = <BehaviorSubject<ShoppingCart[]>>new BehaviorSubject([]);
    this.carts = this._carts.asObservable();
  }

  addData(dataObj:ShoppingCart) {
    this.dataStore.carts.push(dataObj);
    this._carts.next(Object.assign({}, this.dataStore).carts);
  }
}

组件

export class TableQuoteComponent implements OnInit {

  @Input() quote: QuoteSingle = {};
  cart: ShoppingCart;
  serviceSelected : string;

  constructor(private cartService: PrepayService) { }

  ngOnInit() {
  }
  onSubmitAdd(){
    this.cart = {};
    this.cart = this.quote;
    this.cartService.addData(this.cart);

  }
}

第二部分

export class PrePayComponent implements OnInit {
  carts: ShoppingCart[];
  constructor(private cartService: PrepayService) { }

  ngOnInit() {
    this.cartService.carts.subscribe(carts => this.carts = carts);
    console.log(this.carts);
  }

}

数组值 enter image description here enter image description here

2 个答案:

答案 0 :(得分:0)

我认为这是一个参考价值。 Object.assign({}, this.dataStore)将按值复制,而不是引用属性的第一深度。因此,购物车不会按值复制,而是会按引用复制。因此,我假设这里发生的事情是您添加一个新的“ Quote”并添加到添加到主题流中的购物车中。但是,当您重新分配this.quote时,您也在更改dataStore中的值,因此也更改了主题,因为它是通过引用复制的。

要解决此问题,请按如下所示修改服务的addData()方法:

this.dataStore.carts.push(deepCopy(dataObj); // Here we need to deep copy the ShoppingCart. I don't know what your structure looks like. JSON.parse(JSON.stringify(dataObj)) will work for a cheap and easy deep copy.
this._carts.next(deepCopy(this.dataStore.carts)); // Deep copy the carts object here.

我不太擅长解释抱歉的事情,但是基本上,这是您遇到的参考文献副本。发生了很多。 其他人可能有更好的解决方案。

答案 1 :(得分:0)

在TableQuote组件中,您正在cart方法中传递cartService.addData属性的引用,并且当您第二次添加时,更改了更改第一个元素的cart属性。您应该像下面那样传递cart属性的副本

this.cartService.addData({...this.cart});

this.cartService.addData(Object.assign({},this.cart));

在javascript或打字稿中,对象和数组是可变的,这意味着当您传递这些变量时,您实际上传递的是引用,而不仅仅是引用的值。