Angular用Subject替代Input实现行hover仅显当前行操作图标
问题原因
所有表格行共用同一个Subject发射的全局布尔值,任意行触发鼠标事件时,所有子组件都会收到同一个状态值,没有区分事件归属的具体行,因此会出现所有行图标同步显示/隐藏的问题。
修复方案(基于RxJS Subject实现,无需修改全局样式)
- 第一步:调整父组件逻辑,发射事件时携带当前行唯一标识
父组件TS代码修改:
父组件HTML代码修改,绑定鼠标事件时传入当前行ID,同时新增行ID输入属性传递给子组件:// 原Subject<boolean>改为携带悬浮状态+行ID的结构 eventsSubject: Subject<{isHover: boolean, rowId: string | number}> = new Subject(); emitEventToChild(isHover: boolean, rowId: string | number) { this.eventsSubject.next({isHover, rowId}) } private filterSubscription: Subscription<ng-container *ngIf="!emptyList else emptyListTemplate"> <tr requestRow *ngFor="let request of requests" (mouseenter)="emitEventToChild(true, request.id)" (mouseleave)="emitEventToChild(false, request.id)" [isRequestRowHighlighted]="eventsSubject.asObservable()" [currentRowId]="request.id" [attr.data-cy-request-id]="request.id" [request]="request" [actionable]="true" [isRequest]="isRequestsList" (delete)="deleteRequest($event)" appMemoTooltip> </tr> </ng-container> - 第二步:调整子组件逻辑,仅处理归属自身行的事件
子组件TS代码修改:
子组件HTML无需修改,原有@Input() isRequestRowHighlighted: Observable<{isHover: boolean, rowId: string | number}> // 新增输入接收当前行ID @Input() currentRowId: string | number isMouseEnter: boolean = false private eventsSubscription: Subscription ngOnInit(): void { this.eventsSubscription = this.isRequestRowHighlighted.subscribe(event => { // 仅当事件携带的行ID与当前行ID匹配时,更新自身图标显示状态 if (event.rowId === this.currentRowId) { this.isMouseEnter = event.isHover } }) } ngOnDestroy(): void { this.eventsSubscription.unsubscribe(); }[ngClass]="{'invisible': !isMouseEnter}"的显隐逻辑可直接复用。
可选优化:如果不需要强制沿用Subject跨组件通信的模式,也可以直接将mouseenter/mouseleave事件绑定在子组件内部的tr元素上,由子组件自行维护isMouseEnter状态,逻辑会更简洁。上述方案完全适配现有项目结构,不需要调整全局样式,也不会破坏原有业务逻辑。
内容的提问来源于stack exchange,提问作者Artamiel
相关产品推荐
相关产品推荐

