Angular 路由更改中断了 Observable 的组件服务关系
Angular Route Change breaks Component Service Relationship for Observables
我有一个 Angular 9 应用程序,它 运行 很高兴使用 'common' 数据的可观察服务。
当我开始构建路由时,而不是将所有组件都放在一个页面上,服务会在第一次加载时加载组件。
但是,在使用路由链接导航到其他地方并导航回来时,所有可观察对象都停止返回值并返回为未定义。
我为此应用程序使用了 Angular CLI 基础路由项目,因此所有主要组件均以标准方式设置。
在下面的示例代码中,用户和 canEdit 在使用 routelink 导航后返回为未定义,但在第一次加载时工作正常。
用户服务:
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { IUser } from '../interfaces/iuser';
@Injectable({
providedIn: 'root'
})
export class UsersService {
user$: Observable<IUser>;
private userSubject = new Subject<IUser>();
constructor() {
this.user$ = this.userSubject.asObservable();
}
user(data) {
console.log(data)
this.userSubject.next(data);
}
}
组件 ts:
import { Component, OnInit } from '@angular/core';
import { UsersService } from 'src/app/services/users.service';
import { IUser } from 'src/app/interfaces/iuser';
@Component({
selector: 'app-exchange-rate',
templateUrl: './exchange-rate.component.html',
styleUrls: ['./exchange-rate.component.scss']
})
export class ExchangeRateComponent implements OnInit {
currentUser: IUser;
title = 'Exchange Rates';
constructor(
private users: UsersService,
) {
this.users.user$.subscribe((user) => {
this.currentUser = user;
});
}
ngOnInit(): void {
}
get canEdit() {
if (this.currentUser.types.includes('admin')){
return true;
}
else {
return false;
}
}
}
组件html:
<div>
<ng-container *ngIf="canEdit; else fx1">
Can Edit
</ng-container>
<ng-template #fx1>
Cant Edit
</ng-template>
</div>
带 routerLink 的侧边栏组件:
<a class="cell" routerLinkActive="active" [routerLink]="['exchange-rate']">Exchange Rate</a>
//... more routes...
应用路由:
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [{
path: 'exchange-rate',
component: ExchangeRateComponent
},
{
path: 'other-pages',
component: OtherPagesComponent
},
// ... etc
返回组件时报错为
ERROR TypeError: Cannot read property 'types' of undefined
at ExchangeRateComponent.get canEdit [as canEdit]
userSubject
,并且推而广之,user$
在调用 userSubject.next(data)
时发出一次。所以它并没有完全“停止返回值”,因为它没有任何新内容可说。
一个解决方法是将 userSubject
设为 ReplaySubject
(它将向新订阅者发送最后一个值):
userSubject: ReplaySubject<IUser> = new ReplaySubject(1);
我有一个 Angular 9 应用程序,它 运行 很高兴使用 'common' 数据的可观察服务。 当我开始构建路由时,而不是将所有组件都放在一个页面上,服务会在第一次加载时加载组件。
但是,在使用路由链接导航到其他地方并导航回来时,所有可观察对象都停止返回值并返回为未定义。
我为此应用程序使用了 Angular CLI 基础路由项目,因此所有主要组件均以标准方式设置。
在下面的示例代码中,用户和 canEdit 在使用 routelink 导航后返回为未定义,但在第一次加载时工作正常。
用户服务:
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { IUser } from '../interfaces/iuser';
@Injectable({
providedIn: 'root'
})
export class UsersService {
user$: Observable<IUser>;
private userSubject = new Subject<IUser>();
constructor() {
this.user$ = this.userSubject.asObservable();
}
user(data) {
console.log(data)
this.userSubject.next(data);
}
}
组件 ts:
import { Component, OnInit } from '@angular/core';
import { UsersService } from 'src/app/services/users.service';
import { IUser } from 'src/app/interfaces/iuser';
@Component({
selector: 'app-exchange-rate',
templateUrl: './exchange-rate.component.html',
styleUrls: ['./exchange-rate.component.scss']
})
export class ExchangeRateComponent implements OnInit {
currentUser: IUser;
title = 'Exchange Rates';
constructor(
private users: UsersService,
) {
this.users.user$.subscribe((user) => {
this.currentUser = user;
});
}
ngOnInit(): void {
}
get canEdit() {
if (this.currentUser.types.includes('admin')){
return true;
}
else {
return false;
}
}
}
组件html:
<div>
<ng-container *ngIf="canEdit; else fx1">
Can Edit
</ng-container>
<ng-template #fx1>
Cant Edit
</ng-template>
</div>
带 routerLink 的侧边栏组件:
<a class="cell" routerLinkActive="active" [routerLink]="['exchange-rate']">Exchange Rate</a>
//... more routes...
应用路由:
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [{
path: 'exchange-rate',
component: ExchangeRateComponent
},
{
path: 'other-pages',
component: OtherPagesComponent
},
// ... etc
返回组件时报错为
ERROR TypeError: Cannot read property 'types' of undefined
at ExchangeRateComponent.get canEdit [as canEdit]
userSubject
,并且推而广之,user$
在调用 userSubject.next(data)
时发出一次。所以它并没有完全“停止返回值”,因为它没有任何新内容可说。
一个解决方法是将 userSubject
设为 ReplaySubject
(它将向新订阅者发送最后一个值):
userSubject: ReplaySubject<IUser> = new ReplaySubject(1);