简体   繁体   English

为什么在数组推送/拼接时可观察到的结果不会改变

[英]Why observable result won't change while array push/splice

I have a service like this:我有这样的服务:

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

and I subscribe the getItems() observable in my component for my further purpose:并且我订阅了组件中的 getItems() 可观察对象,以用于我的进一步目的:

this.arrService.getItems().subscribe(res => {
  this._arr = res;
});

All the action is directly call the function in ArrService.所有的动作都是直接调用 ArrService 中的 function。 When I called the setValue(), the source array in ArrService and local array in component both changed.当我调用 setValue() 时,ArrService 中的源数组和组件中的本地数组都发生了变化。 And I record that the obseravble didn't emit again while change, so I guess that the obserables should be pass by reference.而且我记录了 observable 在更改时没有再次发出,所以我猜 oberables 应该通过引用传递。

But when I called the addItem() and removeItem(), the source change, but the local didn't.但是当我调用 addItem() 和 removeItem() 时,源发生了变化,但本地没有。 So the obserable isn't pass by reference?所以 oberable 不是通过引用传递的吗? Or I'm misunderstanding how obseravble work?或者我误解了 observable 的工作原理?

I know subject or behaviourSubject can complete my service.我知道主题或行为主题可以完成我的服务。 But I wanna know how the observable functional in this case, why some action is follow but some doesn't.但是我想知道在这种情况下可观察到的功能如何,为什么会遵循一些动作而没有遵循一些动作。

Try Subject尝试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();
  }
}

Use BehaviorSubject if you want to retain the last emitted value (useful in cases when you are subscribing after you have emitted value using .next() )如果您想保留最后发出的值,请使用BehaviorSubject (在您使用.next()发出值后订阅的情况下很有用)


When you work with arrays, there is always problem associated to monitor any changes that has been made in it.当您使用 arrays 时,总是存在与监控其中所做的任何更改相关的问题。 You'll encounter similar behavior in other angular places as well where if you insert any new value to an array, the "ngOnChange" or even "zone.js" wont detect any change in value.你会在其他 angular 地方遇到类似的行为,如果你在数组中插入任何新值,“ngOnChange”甚至“zone.js”都不会检测到值的任何变化。 In such cases, either you create new array reference or handle it manually . 在这种情况下,您要么创建新的数组引用,要么手动处理它

A subject is a type of observable.主题是一种可观察对象。 As such, it is a stream.因此,它是 stream。 You can add an item (such as a number) to the stream and the item will be broadcast to any observers of the stream.您可以向 stream 添加项目(例如数字),该项目将广播给 stream 的任何观察者。

private arr = new Subject<any[]>();

Or if you need default value:或者,如果您需要默认值:

private arr = new BehaviorSubject<any[]>([1,2,3]);

raise event in setValue this way:以这种方式在 setValue 中引发事件:

  setValue(index: number, value: number): void {
    this.arr.next(value);
  }

change the getItems this way:以这种方式更改 getItems:

  getItems(): Observable<any> {
    return this.arr.asObservable();
  }

Final Result:最后结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM