Angular 重新初始化组件后订阅未定义

Angular Subscription gets undefined after re-initializing component

我有一个带有值选择选项的组件 。 我订阅了它在所有其他组件中的初始化值。从第一次初始化开始,该值是 returned,但在我更改组件并返回 return 后,该值未定义。创建该服务是为了将值设置为可观察的。

@Injectable({
  providedIn: 'root',
})
export class LocationFilterService {

  private chooseLocations = new Subject<string[]>();

  chosenLocation$ = this.chooseLocations.asObservable();

  chosenLocations(locations: string[]): void {
    this.chooseLocations.next(locations);
  }
}

我在选择组件中使用了这个服务。 这是选择器 Component

<mat-select (selectionChange)="onSelection($event)" [(value)]="selected">
  <mat-option [value]="allLocationsOption">All Locations</mat-option>
  <mat-option *ngFor="let location of locations.data" [value]="[location.id.toString()]">
<!-- The value is either one item or multiple -->
        {{location.name}}
  </mat-option>
</mat-select>

以及我如何使用 LocationFilterService 设置值

export class LocationFilterComponent implements OnInit {
  ...
  constructor(private locationFilterService: LocationFilterService) {
  }

  ngOnInit(): void {
    this.locationFilterService.chosenLocations(['1']); //default value as an example
  }

 onSelection(event: MatSelectChange) {
    this.selectedLocations = [];
    this.selectedLocations = event.value;
    this.locationFilterService.chosenLocations(this.selectedLocations);
  }
}

当我第一次在树中的任何其他组件中订阅它的值时,它运行良好

export class ExampleComponent implements OnInit, OnDestroy {
     subscription: Subscription;
     chosenLocations: string[];

     constructor(
     private locationFilterService: LocationFilterService) {}

     ngOnInit(): void {
       this.subscription = this.locationFilterService.chosenLocation$.subscribe(
       (loc_id) => {
           this.chosenLocations = loc_id;
           this.doSomeStuff();
           //Do some API call with chosenLocations values. First time it works, but once I 
           //leave this component and return back then this.chosenLocations is undefined
  }
);

    ngOnDestroy(): void {
    this.subscription.unsubscribe(); 
    }
}

尽管我在此示例中将默认值设置为 ['1'],但在组件被销毁并再次初始化后它会变得未定义。这 LocationFilterComponent 始终出现在依赖此值的其他组件之上。目标是在此 LocationFilterComponent 下呈现的其他组件中维护此选择值。每个呈现的新组件都订阅和取消订阅 LocationFilterService。 这个问题的解决方案是什么?我在这个机制中缺少什么? Angular 版本 10

这里的问题是您使用的是 Subject。 相反,你应该使用 BehaviorSubject.

一个 BehaviorSubject 持有一个值。当它被订阅时,它会立即发出值。 Subject 没有值。

主题示例(使用 RxJS 5 API):

const subject = new Rx.Subject();
subject.next(1);
subject.subscribe(x => console.log(x));

Console output will be empty

行为主题示例:

const subject = new Rx.BehaviorSubject(0);
subject.next(1);
subject.subscribe(x => console.log(x));

Console output: 1


@Injectable({
  providedIn: 'root',
})
export class LocationFilterService {

  private chooseLocations = new BehaviorSubject<string[]>(null);

  chosenLocation$ = this.chooseLocations.asObservable();

  chosenLocations(locations: string[]): void {
    this.chooseLocations.next(locations);
  }
}