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);
}
}
我有一个带有值选择选项的组件
@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);
}
}