为什么可观察结果不会改变而数组 push/splice
Why observable result won't change while array push/splice
我有这样的服务:
export class ArrService {
private arr: any[] = [1,2,3];
constructor() {}
setValue(index: number, value: number): void {
this.arr[index]= value;
}
addItem(value: any): void {
this.arr.push(element);
}
removeItem(index: number): void {
this.arr.splice(index, 1);
}
getItems(): Observable<any> {
return of(this.arr);
}
}
并且为了进一步的目的,我订阅了组件中可观察到的 getItems():
this.arrService.getItems().subscribe(res => {
this._arr = res;
});
所有的动作都是直接调用ArrService中的函数。
当我调用 setValue() 时,ArrService 中的源数组和组件中的本地数组都发生了变化。
而且我记录了 obseravble 在更改时没有再次发出,所以我猜 observables 应该通过引用传递。
但是当我调用addItem() 和removeItem() 时,源改变了,而本地没有。
那么 observable 不是通过引用传递的吗?或者我误解了 obseravble 的工作原理?
我知道主题或行为主题可以完成我的服务。
但我想知道在这种情况下 observable 是如何发挥作用的,为什么有些动作会被执行而有些不会。
主题是一种可观察对象。因此,它是一个流。您可以向流中添加一个项目(例如一个数字),该项目将广播给流的任何观察者。
private arr = new Subject<any[]>();
或者如果您需要默认值:
private arr = new BehaviorSubject<any[]>([1,2,3]);
以这种方式在 setValue 中引发事件:
setValue(index: number, value: number): void {
this.arr.next(value);
}
以这种方式更改 getItems:
getItems(): Observable<any> {
return this.arr.asObservable();
}
最终结果:
@Injectable()
export class ArrService {
private arr = new BehaviorSubject<any[]>([1,2,3]);
constructor() {}
setValue(index: number, value: number): void {
let tst = this.arr.value;
tst.push(value);
this.arr.next(tst);
}
getItems(): Observable<any> {
// return of(this.arr);
return this.arr.asObservable();
}
}
尝试Subject
export class ArrService {
private arr: any[] = [1,2,3];
private arr$ = new Subject();
constructor() {}
setValue(index: number, value: number): void {
this.arr[index]= value;
this.arr$.next(this.arr);
}
addItem(value: any): void {
this.arr.push(element);
this.arr$.next(this.arr);
}
removeItem(index: number): void {
this.arr.splice(index, 1);
this.arr$.next(this.arr);
}
getItems(): Observable<any> {
return this.arr$.asObservable();
}
}
如果要保留最后发出的值,请使用 BehaviorSubject
(在使用 .next()
发出值后进行订阅的情况下很有用)
当您使用数组时,始终存在与监视其中所做的任何更改相关的问题。你会在其他 angular 地方遇到类似的行为,如果你向数组插入任何新值,“ngOnChange”甚至“zone.js”都不会检测到值的任何变化。 .
我有这样的服务:
export class ArrService {
private arr: any[] = [1,2,3];
constructor() {}
setValue(index: number, value: number): void {
this.arr[index]= value;
}
addItem(value: any): void {
this.arr.push(element);
}
removeItem(index: number): void {
this.arr.splice(index, 1);
}
getItems(): Observable<any> {
return of(this.arr);
}
}
并且为了进一步的目的,我订阅了组件中可观察到的 getItems():
this.arrService.getItems().subscribe(res => {
this._arr = res;
});
所有的动作都是直接调用ArrService中的函数。 当我调用 setValue() 时,ArrService 中的源数组和组件中的本地数组都发生了变化。 而且我记录了 obseravble 在更改时没有再次发出,所以我猜 observables 应该通过引用传递。
但是当我调用addItem() 和removeItem() 时,源改变了,而本地没有。 那么 observable 不是通过引用传递的吗?或者我误解了 obseravble 的工作原理?
我知道主题或行为主题可以完成我的服务。 但我想知道在这种情况下 observable 是如何发挥作用的,为什么有些动作会被执行而有些不会。
主题是一种可观察对象。因此,它是一个流。您可以向流中添加一个项目(例如一个数字),该项目将广播给流的任何观察者。
private arr = new Subject<any[]>();
或者如果您需要默认值:
private arr = new BehaviorSubject<any[]>([1,2,3]);
以这种方式在 setValue 中引发事件:
setValue(index: number, value: number): void {
this.arr.next(value);
}
以这种方式更改 getItems:
getItems(): Observable<any> {
return this.arr.asObservable();
}
最终结果:
@Injectable()
export class ArrService {
private arr = new BehaviorSubject<any[]>([1,2,3]);
constructor() {}
setValue(index: number, value: number): void {
let tst = this.arr.value;
tst.push(value);
this.arr.next(tst);
}
getItems(): Observable<any> {
// return of(this.arr);
return this.arr.asObservable();
}
}
尝试Subject
export class ArrService {
private arr: any[] = [1,2,3];
private arr$ = new Subject();
constructor() {}
setValue(index: number, value: number): void {
this.arr[index]= value;
this.arr$.next(this.arr);
}
addItem(value: any): void {
this.arr.push(element);
this.arr$.next(this.arr);
}
removeItem(index: number): void {
this.arr.splice(index, 1);
this.arr$.next(this.arr);
}
getItems(): Observable<any> {
return this.arr$.asObservable();
}
}
如果要保留最后发出的值,请使用 BehaviorSubject
(在使用 .next()
发出值后进行订阅的情况下很有用)
当您使用数组时,始终存在与监视其中所做的任何更改相关的问题。你会在其他 angular 地方遇到类似的行为,如果你向数组插入任何新值,“ngOnChange”甚至“zone.js”都不会检测到值的任何变化。