BehaivorSubject не хранить массив и дублировать

У меня есть служба и компонент, когда я добавляю значение, которое сохраняется в массиве, но когда я добавляю другое, мое первое значение меняет значение на второе.

обслуживание

 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);
  }

}

Значения массива введите описание изображения здесь введите описание изображения здесь

2 ответа

Решение

В вашем компоненте TableQuote вы передаете ссылку cart недвижимость в cartService.addData метод, и когда вы добавляете второй раз, вы меняете cart свойство, которое изменяет первый элемент. Вы должны передать копию cart собственность как ниже

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

или же

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

В javascript или машинописном объекте объекты и массивы являются изменяемыми, что означает, что когда вы передаете эти переменные, вы фактически передаете ссылку, а не только ее значение.

Я думаю, что это значение по ссылке.Object.assign({}, this.dataStore) будет копировать по значению вместо ссылки для первой глубины свойств. Таким образом, тележки не будут скопированы по значению, они будут скопированы по ссылке. Итак, я предполагаю, что здесь происходит то, что вы добавляете новую цитату и добавляете в корзину, которая добавляется в тематический поток. Но когда вы переназначаете this.quote Вы также изменяете значение в хранилище данных и, следовательно, тему, поскольку оно копируется по ссылке.

Чтобы это исправить, измените метод 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.

Я не очень хорошо объясняю вещи, извините, но в основном это проблема с копией по ссылке, с которой вы столкнулись. Бывает много. У кого-то еще может быть лучшее решение.

Другие вопросы по тегам