【问题标题】:Angular Subscription gets undefined after re-initializing component重新初始化组件后,Angular Subscription 未定义
【发布时间】:2021-07-26 13:42:52
【问题描述】:

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

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

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

  chosenLocation$ = this.chooseLocations.asObservable();

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

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

<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 订阅和取消订阅。 这个问题的解决方案是什么,我在这个机制中缺少什么?角度版本 10

【问题讨论】:

  • 看来您需要用 BehaviorSubject 或 ReplaySubject 替换您的主题。然后在使用您的组件进行新订阅时,它将获得起始值。

标签: angular angular10


【解决方案1】:

这里的问题是您正在使用主题。 相反,您应该使用 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);
  }
}

【讨论】:

  • 这就是解决方案。我刚刚在我的环境中进行了测试,它可以工作。谢谢你,德拉什蒂!
  • 很高兴我能帮上忙。
  • 你能告诉我哪个 RxJS 版本对于这个解决方案是稳定的吗?
  • 这将取决于您使用的角度版本。但是,Behavior 主题从一开始就是 rxjs 的一部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 2022-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多