javascript - Angular rxjs主题:在发出值后订阅主题
问题描述
我读过一篇文章,其中指出,如果您在事件已经发出时订阅主题,您将丢失发出的值。他的演示示例如下。
let subject: Subject<string> = new Subject();
subject.next('test');
subject.subscribe((event) => {
console.log(event);
});
但是,我实现了类似的方法,其中第一个主题将发出值,然后订阅主题。价值就在那里。没有丢失。代码如下。在代码中,我们将身份验证信息保存在主题中。我们在标题组件中使用它来显示注销按钮和链接。问题是为什么我的代码可以工作,即使文章说它不会?
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Subject} from "rxjs";
import { User } from "./user.model";
@Injectable({providedIn : "root"})
export class AuthService{
constructor(private httpClient:HttpClient){}
user = new Subject<User>(); //emit new user when login or logout or token expired
login(email:string,password:string){
return this.httpClient
.post<SignUpResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyBCK9B2RcL0D4Bn8YaFCxE9rBXejTLNYQY',
{
email:email,
password:password,
returnSecureToken:true
})
.pipe(tap( response => this.handleAuthentication(response.email,response.idToken,response.idToken,response.expiresIn)))
}
private handleAuthentication(email:string,userId:string,token:string,expiresIn:string){
const expirationDate = new Date(new Date().getTime() + +expiresIn * 1000)
const user = new User(email,userId,token,expirationDate);
this.user.next(user);
}
}
头文件.component.ts
import { Component,Output, EventEmitter, OnInit, OnDestroy } from "@angular/core";
import { Subscription } from "rxjs";
import { AuthService } from "../auth/auth/auth.service";
import { DataStorageService } from "../shared/data-storage.service";
@Component({
selector : 'app-header',
templateUrl:'./header.component.html'
})
export class HeaderComponent implements OnInit,OnDestroy{
collapsed = true;
private subscription : Subscription;
isAuthenticated : boolean = false;
constructor(private dataStorageService:DataStorageService,
private authService:AuthService){
}
ngOnInit(){
this.subscription = this.authService.user.subscribe( user => {
this.isAuthenticated = !!user;
console.log("User Object"); console.log(user);
console.log("IsAuthenticated value"); console.log(!!user);
})
}
ngOnDestroy(){
this.subscription.unsubscribe();
}
}
解决方案
您的示例订阅正在运行的唯一原因是因为您在启动登录过程/方法之前加载了 Header 组件。ngOnInit
在服务中的方法之前调用组件login
。
您的代码运行方式不是您在问题中描述的方式:
user = new Subject<User>();
subject.next('test');
// then this runs in component ngOnInit
this.authService.user.subscribe((event) => {
console.log(event);
});
// when you try to login from inside the component then it runs the login method with next.
login(email:string,password:string){.....
this.user.next(user); // now this is triggered hence you don't loose the user response.
推荐阅读
- c# - 'Func<,>' 类型在未引用的程序集中定义。您必须添加对程序集 'netstandard; 的引用;C#; 添加 ref 不起作用
- python - 如何在 Scrapy 中抓取稍后通过 ajax 获取部分数据的页面?
- c# - Azure 管道 - '名称空间中不存在类型或名称空间名称'基础结构''
- javascript - 如何检测 HTML 视频是否受到 Chrome 中的 javascript 的 DRM 保护?
- merge - ImageMagick:将多个 PNG 图像裁剪并合并为一个 PDF 时,页面会移出视图
- c++ - c ++模板成员函数,在类外具有部分特殊化
- amazon-web-services - Terraform Cognito 用户池
- html - 如何使用 flexbox 列和悬停水平 div?
- regex - Ruby:为正则表达式扫描二进制 IO
- javascript - 如何更改 Vuetify 日历中事件的边框颜色?