如何在Angular中不使用<app-login>标签,通过@Output和EventEmitter传递UUID
问题描述
点击login.component.html中定义的“Next”按钮后,需要将login.component.ts中生成的UUID传递到login-challenge.component.ts中。尝试使用@Output和EventEmitter实现但未成功,核心问题是多数方案需要使用<app-login>标签,会加载login组件的全部HTML,而我不想使用该标签。
相关代码
login.component.ts
@Output() uuid = new EventEmitter<string>() onSubmit() { if (this.loginForm.valid) { // this.isLoading = true this.authService.auth(this.loginForm.value).subscribe((data: User[]) => { this.dataSource = data // console.log(data) this.uuid.emit(`this is the sent data from login.... ${this.dataSource}`) /* setTimeout(() => { },2000) */ this.router.navigate([`/login-challenge`]) } //include error message alert here--> /* , (_e) => { alert("User Not Found! Please enter valid credentials.") } */ ) } }
login.component.html
<button mat-raised-button color="primary" class="btn" (click)="onSubmit()"> Next </button>
login-challenge.component.ts
uuid! : string receiveMessage($event: string) { this.uuid = $event; console.log("this.uuid :-", this.uuid) } onSubmit() { console.log("uuid from login component :- ",this.uuid) if(this.loginChallengeForm.valid){ this.isLoading = true console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!") this.authService.challenge(this.loginChallengeForm.value).subscribe((token) =>{ localStorage.setItem(this.tokenKey, token) console.log(token) alert("Verified User...now navigating!") const role = this.loginChallengeForm.value["userType"]; if (this.authService.isAuthenticated()) { console.log("Login done navigating to home"); this.router.navigate([`${role}/home/dashboard`]) } }) } }
login-challenge.component.html
<h2 (uuid)="receiveMessage($any($event))"></h2> <h2>{{uuid}}</h2>
解决方案
为什么@Output不适用?
@Output和EventEmitter是父子组件间的通信机制,要求父组件通过标签(如<app-login>)引用子组件,才能监听子组件的输出事件。但你现在是通过路由跳转两个独立组件,不属于父子关系,所以这种方案不适用。
以下是三种适合独立路由组件间传递数据的方案:
方案1:路由查询参数传递
直接通过路由跳转时携带UUID作为查询参数,目标组件从路由中提取参数。
- 修改login.component.ts的跳转逻辑:
onSubmit() { if (this.loginForm.valid) { this.authService.auth(this.loginForm.value).subscribe((data: User[]) => { this.dataSource = data; // 替换为实际生成的UUID值 const targetUuid = `这里是实际的UUID`; // 跳转时携带查询参数 this.router.navigate(['/login-challenge'], { queryParams: { uuid: targetUuid } }); }); } }
- 在login-challenge.component.ts中获取参数:
import { ActivatedRoute } from '@angular/router'; // 构造函数注入ActivatedRoute constructor(private route: ActivatedRoute) {} ngOnInit() { // 订阅路由参数变化 this.route.queryParams.subscribe(params => { this.uuid = params['uuid'] || ''; console.log('获取到的UUID:', this.uuid); }); }
方案2:Angular共享服务传递数据
创建一个全局共享服务,用来存储和传递UUID,适用于需要在多个组件间共享数据的场景。
- 创建共享服务:
// shared-data.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SharedDataService { // 使用BehaviorSubject保存UUID,确保订阅者能获取最新值 private uuidSubject = new BehaviorSubject<string>(''); currentUuid = this.uuidSubject.asObservable(); // 设置UUID的方法 setUuid(uuid: string) { this.uuidSubject.next(uuid); } }
- 在login.component.ts中设置UUID:
import { SharedDataService } from './shared-data.service'; // 注入共享服务 constructor(private sharedDataService: SharedDataService) {} onSubmit() { if (this.loginForm.valid) { this.authService.auth(this.loginForm.value).subscribe((data: User[]) => { this.dataSource = data; const targetUuid = `这里是实际的UUID`; // 通过服务设置UUID this.sharedDataService.setUuid(targetUuid); this.router.navigate(['/login-challenge']); }); } }
- 在login-challenge.component.ts中获取UUID:
import { SharedDataService } from './shared-data.service'; // 注入共享服务 constructor(private sharedDataService: SharedDataService) {} ngOnInit() { // 订阅UUID的变化 this.sharedDataService.currentUuid.subscribe(uuid => { this.uuid = uuid; console.log('获取到的UUID:', this.uuid); }); }
方案3:localStorage临时存储
如果UUID不需要长期保存,可临时存在localStorage中,跳转后读取并清除。
- 在login.component.ts中存储UUID:
onSubmit() { if (this.loginForm.valid) { this.authService.auth(this.loginForm.value).subscribe((data: User[]) => { this.dataSource = data; const targetUuid = `这里是实际的UUID`; // 存入localStorage localStorage.setItem('tempLoginUuid', targetUuid); this.router.navigate(['/login-challenge']); }); } }
- 在login-challenge.component.ts中读取并清除:
ngOnInit() { // 读取UUID this.uuid = localStorage.getItem('tempLoginUuid') || ''; console.log('获取到的UUID:', this.uuid); // 用完后清除临时存储 localStorage.removeItem('tempLoginUuid'); }
内容的提问来源于stack exchange,提问作者Ninja G
相关产品推荐
相关产品推荐

