Angular中<router-outlet>子组件向父组件传值失败的原因与解决
问题原因
<router-outlet>是Angular内置的路由渲染组件,核心作用是根据当前路由规则匹配并渲染对应组件,它本身并没有你定义的(un)输出事件。而<app-login>是你自定义的组件,你在组件内部通过@Output() un = new EventEmitter()声明了这个输出事件,所以能直接绑定触发。直接给router-outlet绑定自定义事件,Angular无法识别,自然没法完成传值。
解决方法
方法一:用共享服务实现组件通信(推荐)
这是Angular中路由组件与父组件通信的标准方案,步骤如下:
- 创建一个共享服务,比如
UserService:
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserService { private userNameSubject = new Subject<string>(); userName$ = this.userNameSubject.asObservable(); sendUserName(name: string) { this.userNameSubject.next(name); } }
- 在路由组件(比如登录后跳转的页面组件)中注入服务,调用方法发送数据:
import { Component } from '@angular/core'; import { UserService } from './user.service'; @Component({ selector: 'app-target-route', template: `...` }) export class TargetRouteComponent { constructor(private userService: UserService) {} triggerUserChange(name: string) { this.userService.sendUserName(name); } }
- 在
AppComponent中订阅服务的数据流:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { UserService } from './user.service'; import { Subscription } from 'rxjs'; export class AppComponent implements OnInit, OnDestroy { title = 'order'; uname = 'guest'; private subscription!: Subscription; constructor(private userService: UserService) {} ngOnInit() { this.subscription = this.userService.userName$.subscribe(name => { console.log("name", name); this.uname = name; }); } ngOnDestroy() { this.subscription.unsubscribe(); } }
方法二:通过@ViewChild获取路由组件实例监听事件
适合简单场景,需注意路由组件的加载时机:
- 在
AppComponent中获取RouterOutlet实例,监听激活组件的事件:
import { Component, ViewChild, OnInit } from '@angular/core'; import { RouterOutlet } from '@angular/router'; export class AppComponent implements OnInit { title = 'order'; uname = 'guest'; @ViewChild(RouterOutlet) routerOutlet!: RouterOutlet; ngOnInit() { this.routerOutlet.activateEvents.subscribe((component: any) => { if (component.un) { component.un.subscribe(name => { console.log("name", name); this.uname = name; }); } }); } }
- 确保路由组件内部同样定义了
@Output() un = new EventEmitter<string>(),和<app-login>组件的写法一致。
内容的提问来源于stack exchange,提问作者GabrijelOkorn
相关产品推荐
相关产品推荐

