angular - Angular Route Change 破坏了 Observables 的组件服务关系
问题描述
我有一个 Angular 9 应用程序,它运行愉快,可观察到的“通用”数据服务。当我开始构建路由时,不是将所有组件都放在一个页面上,而是在首次加载时使用组件加载服务。
但是,在使用 routerlink 导航到其他地方并返回时,所有可观察对象都停止返回值并以未定义的形式返回。
我为此应用程序使用了 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);
推荐阅读
- react-native - 导航到其他屏幕时的 React Navigation 4.x 版本问题
- angular - ng-boostrap:ESC 按键上的模态关闭不起作用
- apache-flink - flink 中是否有官方的 session scheduler 接口允许用户自定义 session 管理?
- javascript - document.getElementById 为空,加载了延迟大小的 iframe
- javascript - 为什么 form.append 不附加多个文件?
- apache-kafka - 卡夫卡消息处理
- javascript - 如何对javascript进行真实检查
- python - 如何检查 Pandas df 行中的元素是否具有等号的值(符号更改后的值)
- html - Highcharts 错误 #13:www.highcharts.com/errors/13 - Angular
- ibm-cloud - 如何查找 API 详细信息,例如 IBM Watson Assistant 的 URL 和凭证