You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular routerLink激活时router-outlet内*ngIf使用及传值问题

问题原因

你的代码存在4个核心错误,导致绑定逻辑和路由导航完全不生效:

  • 核心认知错误:<router-outlet>是Angular路由的占位容器,不是普通组件宿主标签,你不能像写自定义组件标签那样,直接在<router-outlet>上写[model]输入绑定、(modelChanged)输出绑定,这些属性不会被传递到路由动态加载的组件上。
  • activate事件用法完全错误:activate是<router-outlet>提供的内置事件,仅在路由激活、组件实例创建完成时触发,事件返回值是当前加载的组件实例,不支持在事件绑定表达式里嵌套写模板输入输出语法,你写的(activate)='[model]="model" (modelChanged)="modelChangeHandler($event)"'属于无效模板语法,Angular无法正常解析执行。
  • 路由配置与模板不匹配:你给两个子路由都配置了命名出口(rangeConge、multipleConge),但模板里只写了一个无名称的默认<router-outlet>,同时routerLink也没有指定要渲染到的命名出口,路由加载的组件找不到对应的渲染位置。
  • 无效的结构指令写法:模板里写的*ngif="routerlink"存在两个问题,一是ngIf大小写拼写错误,二是父组件类里根本没有定义routerlink变量,判断结果恒为假,<router-outlet>会被直接从DOM中移除,根本不会加载任何路由组件。
正确实现方案

方案1:保留路由加载模式,通过activate事件绑定输入输出

第一步:修正路由配置

标签页导航用默认无名出口即可,移除多余的命名出口配置:

// app-routing.module.ts
{
  path:'congeComponent',
  component:CongeComponentComponent,
  children:[
    {
      path:'demandeConge',
      component:DemandeCongeComponent
    },
    {
      path:'demandeMultipleDays',
      component:DemandeMultipleDaysComponent
    }
  ]
}

第二步:修正父组件模板

移除无效的*ngIf和错误的绑定写法,仅保留activate事件绑定:

<nav mat-tab-nav-bar dynamicHeight>
  <a mat-tab-link *ngFor="let tabItem of tabs" [routerLink]="tabItem.route" routerLinkActive #rla="routerLinkActive"
    [active]="rla.isActive">
    {{tabItem.label}}
  </a>
</nav>

<router-outlet (activate)="onRouteActivate($event)"></router-outlet>

第三步:在父组件类中手动处理组件实例绑定

拿到路由加载的组件实例后,手动给输入属性赋值、订阅输出事件:

// 父组件ts文件
onRouteActivate(componentRef: any) {
  // 匹配当前激活的多日申请组件
  if(componentRef instanceof DemandeMultipleDaysComponent) {
    // 手动传递输入属性
    componentRef.model = this.model;
    // 手动订阅输出事件
    componentRef.modelChanged.subscribe((newModel: Date[]) => {
      this.modelChangeHandler(newModel);
    })
  }
  // 其他路由组件的输入输出绑定可在此处扩展判断
}

如果需要保留标签切换时的组件状态,可以配合RouteReuseStrategy做路由复用,避免组件重复销毁重建。


方案2:非路由加载模式(更简单的标签实现)

如果不需要URL同步标签状态、不需要支持链接直达指定标签,可以放弃路由加载子组件,直接通过routerLinkActive的激活状态控制组件显示,原生输入输出绑定可以直接生效:

<nav mat-tab-nav-bar dynamicHeight>
  <a mat-tab-link routerLink="demandeConge" routerLinkActive #rlaRange="routerLinkActive"
    [active]="rlaRange.isActive" [routerLinkActiveOptions]="{exact: true}">
    Range of days
  </a>
  <a mat-tab-link routerLink="demandeMultipleDays" routerLinkActive #rlaMultiple="routerLinkActive"
    [active]="rlaMultiple.isActive" [routerLinkActiveOptions]="{exact: true}">
    Multiple days
  </a>
</nav>

<app-demande-conge *ngIf="rlaRange.isActive"></app-demande-conge>
<app-demandeMultipleDays *ngIf="rlaMultiple.isActive" [model]="model" (modelChanged)="modelChangeHandler($event)"></app-demandeMultipleDays>

这种写法不需要手动处理路由实例绑定,逻辑更直观,缺点是组件切换时默认会销毁重建,URL不会同步当前选中的标签状态。

内容的提问来源于stack exchange,提问作者Mouad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 04:33:43