【问题标题】:use Angular Observable subscribed value in Component在组件中使用 Angular Observable 订阅值
【发布时间】:2021-10-28 23:08:27
【问题描述】:

我在 Angular 中有以下问题:

A.用户服务订阅了一个 oAuth 提供者,然后,它将一个名为 activeUserId 的属性设置为从 observable 接收到的值。

B. 5 个组件有一个调用 backendServices 的 onClick() 方法。这些服务接受 number 类型的输入参数“activeUserId”。

确保仅在实际设置了 activeUserId 时才调用“onClick”的最佳方法是什么,或者是否可以将用户服务的可观察对象而不是数字传递给其他服务?我希望不必在每个组件中订阅用户服务 - 确保用户可以单击一个元素来调用服务,即使在用户服务 observable 检索值之前 100 毫秒也是如此。

谢谢 托马斯

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    我相信您想要做的是在路由加载前验证用户的身份验证。这样,您始终可以确保用户的 id 可供使用。一种方法是使用Route Guard。这将确保用户身份验证预路由加载。

    在此示例中,我将用户数据存储在本地存储中,以便当用户刷新页面或意外点击时,他们的身份验证基于存储中用户对象与内存中用户对象的令牌到期时间。

    如果用户通过验证,您可以安全地调用用户的内存值而无需订阅。

    auth.guard.ts

    import { Injectable } from '@angular/core';
    import { CanActivate, Router } from '@angular/router';
    import { StorageService } from '../services/storage.service';
    import { UserService } from '../services/user.service';
    
    @Injectable({ providedIn: 'root' })
    export class AuthGuard implements CanActivate {
      constructor(
        private router: Router,
        private userService: UserService,
        private storageService: StorageService
      ) { }
      canActivate(
      ): Promise<boolean> | boolean {
        return new Promise((resolve) => {
          const userStore = this.userService.user$.value
          if (!userStore.id) {
            const userStorage = this.storageService.get('user')
            if (!userStorage) {
              this.router.navigate(['login'])
              resolve(true)
            } else {
              this.userService.user$.next(userStorage)
              resolve(true)
            }
          } else {
            resolve(true)
          }
        })
      }
    }
    

    main.routes.ts

    {
      path: 'dashboard',
      component: DashboardComponent,
      canActivate: [AuthGuard],
    }
    

    dashboard.component.ts

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-dashboard',
      templateUrl: './dashboard.component.html',
      styleUrls: ['./dashboard.style.scss'],
    })
    export class DashboardComponent {
      constructor(private userService: UserService) {
        const user = this.userService.user$.value
        console.log('user should be active and validated here', user)
       }
    }
    

    【讨论】:

      【解决方案2】:

      我能想到2个简单的策略,当然有很多选择。

      1. 使onClick 调用调用一个外观服务类,该服务类将用户服务注入其中。
      2. activeUserId 设为BehaviorSubject 并订阅更改。例如,一旦您从订阅中收到有效值,您就可以启用该按钮。您也可以对第一个策略执行类似的操作。

      我认为第一种策略更好,因为您可以随意调整外观服务。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-10
        • 2020-01-26
        • 1970-01-01
        • 2020-06-19
        • 2018-05-23
        • 1970-01-01
        • 2023-04-02
        • 2017-11-30
        相关资源
        最近更新 更多