首页 > 解决方案 > 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]

标签: angulartypescriptrxjsangular-routerangular9

解决方案


userSubject, 并且,通过扩展,user$, 发出一次,当userSubject.next(data)被调用时。因此,它并没有完全“停止返回值”,因为它没有什么新东西要说。

一种解决方法是制作userSubject一个ReplaySubject(它将向新订阅者发出最后一个值):

userSubject: ReplaySubject<IUser> = new ReplaySubject(1);

推荐阅读