Angular中带*ngIf的子组件在父组件HTML靠前却后执行是什么原因
问题原因
*ngIf是Angular结构指令,本质是<ng-template [ngIf]="condition">的语法糖,不会和普通静态节点走同一批解析流程- Angular模板渲染规则:无结构指令修饰的静态节点解析优先级,高于结构指令生成的嵌入视图。哪怕
*ngIf的判定条件在组件初始化阶段就为true,<ng-template>包裹的内容也要等当前层级所有静态节点全部完成实例化、绑定逻辑执行后,才会被创建并运行对应的绑定方法 - 你场景中不带
*ngIf的子组件属于静态节点,会先被解析执行,因此check2()会早于带*ngIf子组件的check()执行,和模板书写顺序无关
解决方案
方案1:统一使用*ngIf控制两个组件
给原本不带*ngIf的子组件也添加恒为true的*ngIf条件,此时两个组件都属于嵌入视图,Angular会严格按照模板书写顺序处理,即可保证check()先于check2()执行
<!-- 父组件模板示例 --> <app-child *ngIf="yourCondition" (outputEvent)="check()"></app-child> <app-child *ngIf="true" (outputEvent)="check2()"></app-child>
方案2:改用[hidden]属性替代*ngIf控制显隐
如果不需要组件销毁重建的逻辑,可以把*ngIf换成[hidden]属性控制显隐,此时两个组件都属于静态节点,会按照模板书写顺序解析执行
<!-- 父组件模板示例 --> <app-child [hidden]="!yourCondition" (outputEvent)="check()"></app-child> <app-child (outputEvent)="check2()"></app-child>
注意:[hidden]仅通过CSS的display: none控制显隐,组件实例会一直保留,不会触发销毁/初始化钩子,更适合显隐切换频繁的场景。
方案3:通过事件流控制执行顺序
如果必须保留原有渲染逻辑(一个用*ngIf一个静态),可以借助RxJS的Subject控制两个方法的执行顺序:
// 父组件ts示例 import { Subject, take } from 'rxjs'; export class MyAppComponent { private checkExecuted$ = new Subject<void>(); check() { // 原有check方法的业务逻辑 console.log('check执行'); this.checkExecuted$.next(); } check2() { this.checkExecuted$.pipe(take(1)).subscribe(() => { // 原有check2方法的业务逻辑 console.log('check2执行'); }) } }
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

