BehaviorSubject 不保留数组和重复项
BehaivorSubject not keep array and duplicate
我有一个服务和一个组件,当我添加一个值时,它会保留在数组中,但是当我添加其他值时,我的第一个值会将值更改为第二个
服务
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
我认为这是一个参考值。
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.
抱歉,我不是很擅长解释,但这基本上是您遇到的引用复制问题。经常发生。
其他人可能有更好的解决方案。
在您的 TableQuote 组件中,您在 cartService.addData
方法中传递了 cart
属性 的引用,当您第二次添加时,您更改了 cart
属性 改变第一个元素。你应该传递 cart
属性 的副本,如下所示
this.cartService.addData({...this.cart});
或
this.cartService.addData(Object.assign({},this.cart));
在 javascript 或打字稿中,对象和数组是可变的,这意味着当您传递这些变量时,您实际上传递的是引用,而不仅仅是它的值。
我有一个服务和一个组件,当我添加一个值时,它会保留在数组中,但是当我添加其他值时,我的第一个值会将值更改为第二个
服务
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
我认为这是一个参考值。
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.
抱歉,我不是很擅长解释,但这基本上是您遇到的引用复制问题。经常发生。 其他人可能有更好的解决方案。
在您的 TableQuote 组件中,您在 cartService.addData
方法中传递了 cart
属性 的引用,当您第二次添加时,您更改了 cart
属性 改变第一个元素。你应该传递 cart
属性 的副本,如下所示
this.cartService.addData({...this.cart});
或
this.cartService.addData(Object.assign({},this.cart));
在 javascript 或打字稿中,对象和数组是可变的,这意味着当您传递这些变量时,您实际上传递的是引用,而不仅仅是它的值。