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

Angular中是否有类似React的简洁组件条件显示实现方案?

这种紧凑条件渲染方案在Angular中完全可实现,优先选择结构型指令方案,性能和原生*ngIf完全一致,且不会生成任何额外外层DOM节点,完全符合你的需求。

最优实现方案

方案1:结构型指令实现(更推荐)

结构型指令是Angular原生提供的操作DOM视图的能力,没有多余宿主节点,性能最优,兼容所有Angular版本。

  1. 指令代码:
import { Directive, Input, TemplateRef, ViewContainerRef, OnChanges } from '@angular/core';

@Directive({
  selector: '[ifElse]',
  standalone: true // Angular 14以下版本删除该行,将指令加入对应NgModule的declarations数组
})
export class IfElseDirective implements OnChanges {
  @Input('ifElse') condition: boolean | null | undefined = false;
  @Input() ifElseThen!: TemplateRef<unknown>;
  @Input() ifElseElse!: TemplateRef<unknown>;

  constructor(private viewContainerRef: ViewContainerRef) {}

  ngOnChanges(): void {
    this.viewContainerRef.clear();
    const template = this.condition ? this.ifElseThen : this.ifElseElse;
    if (template) {
      this.viewContainerRef.createEmbeddedView(template);
    }
  }
}
  1. 模板使用(利用Angular微语法,写法更紧凑):
<ng-container *ifElse="loggedIn; then avatarTpl; else signInTpl"></ng-container>

<ng-template #avatarTpl>
  <avatar></avatar>
</ng-template>
<ng-template #signInTpl>
  <sign-in-button></sign-in-button>
</ng-template>

方案2:组件式实现(更贴近你举例的写法)

如果更偏好你举例的包裹式写法,可以用组件实现,配合display: contents消除外层宿主节点的布局影响:

  1. 组件代码:
import { Component, Input, ContentChild, TemplateRef } from '@angular/core';

@Component({
  selector: 'if-else',
  standalone: true,
  template: `
    <ng-container *ngIf="condition; else elseBlock">
      <ng-container *ngTemplateOutlet="ifTpl"></ng-container>
    </ng-container>
    <ng-template #elseBlock>
      <ng-container *ngTemplateOutlet="elseTpl"></ng-container>
    </ng-template>
  `,
  host: {
    'style': 'display: contents'
  }
})
export class IfElseComponent {
  @Input() condition!: boolean | null | undefined;
  @ContentChild('if') ifTpl!: TemplateRef<unknown>;
  @ContentChild('else') elseTpl!: TemplateRef<unknown>;
}
  1. 模板使用:
<if-else [condition]="loggedIn">
  <ng-template #if>
    <avatar></avatar>
  </ng-template>
  <ng-template #else>
    <sign-in-button></sign-in-button>
  </ng-template>
</if-else>

注意:受Angular渲染机制限制,两个分支必须用ng-template包裹,不能直接给普通组件加#if/#else引用,因为普通元素的模板引用拿到的是组件实例而非渲染模板,无法实现动态条件渲染。

扩展能力

可以自行扩展上述实现,直接支持Observable类型的condition参数,自动做订阅和取消订阅处理,不用手动加async管道,进一步简化异步场景的写法。

内容的提问来源于stack exchange,提问作者Greg Van Gorp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:54:03