Angular5使用HostListener与指令实现表格选中行高亮
嘿,这事儿好办!用Angular指令搭配HostListener就能轻松实现表格行选中高亮的效果,我给你一步步拆解实现过程:
实现Angular表格行选中高亮(指令+HostListener)
1. 先创建高亮指令
我们先写一个可复用的指令,用来监听行点击、管理选中状态和高亮样式:
import { Directive, HostListener, ElementRef, Renderer2, Input } from '@angular/core'; @Directive({ selector: '[appHighlightRow]' }) export class HighlightRowDirective { // 支持自定义高亮类名,默认用highlight-row @Input() highlightClass = 'highlight-row'; // 记录当前行是否选中 isSelected = false; constructor(private el: ElementRef, private renderer: Renderer2) { } @HostListener('click') onClick() { // 点击行时切换选中状态 this.isSelected = !this.isSelected; // 根据状态添加/移除高亮类 this.isSelected ? this.renderer.addClass(this.el.nativeElement, this.highlightClass) : this.renderer.removeClass(this.el.nativeElement, this.highlightClass); } // 提供外部调用方法,用于全选/取消全选的批量控制 setSelected(selected: boolean) { this.isSelected = selected; this.isSelected ? this.renderer.addClass(this.el.nativeElement, this.highlightClass) : this.renderer.removeClass(this.el.nativeElement, this.highlightClass); } }
2. 添加高亮样式
在全局样式文件或者组件专属样式里,定义高亮的视觉效果:
.highlight-row { background-color: #e3f2fd; /* 浅蓝色高亮,你可以换成任何喜欢的颜色 */ }
3. 修改表格HTML代码
把指令加到你的表格行上,同时完善全选复选框和单行复选框的逻辑:
<table class="table table-bordered table-condensed table-hover"> <thead> <tr> <th class="text-center"> <input type="checkbox" name="all" (change)="toggleAllRows($event)" /> </th> <th>Level</th> <th>Time</th> <th>Hourly Rate</th> </tr> </thead> <tbody> <tr *ngFor="let level of levels; let i = index" appHighlightRow #rowRef="appHighlightRow"> <td class="text-center"> <input type="checkbox" [(ngModel)]="level.isSelected" (change)="toggleSingleRow(rowRef, level.isSelected)" /> </td> <td>{{level.levelName}}</td> <!-- 替换成你实际的level属性 --> <td>{{level.time}}</td> <td>{{level.hourlyRate}}</td> </tr> </tbody> </table>
4. 组件TS文件处理选中逻辑
在你的组件类里,添加全选/单行选中的联动逻辑,同时给levels数组的每个对象加上isSelected属性:
import { Component, ViewChildren, QueryList } from '@angular/core'; import { HighlightRowDirective } from './highlight-row.directive'; @Component({ selector: 'app-level-table', templateUrl: './level-table.component.html', styleUrls: ['./level-table.component.css'] }) export class LevelTableComponent { // 示例数据,根据你的实际数据调整,记得加上isSelected默认值 levels = [ { levelName: 'Level 1', time: '8h', hourlyRate: '$20', isSelected: false }, { levelName: 'Level 2', time: '8h', hourlyRate: '$25', isSelected: false }, { levelName: 'Level 3', time: '8h', hourlyRate: '$30', isSelected: false } ]; // 获取所有行的指令引用,用于批量控制 @ViewChildren(HighlightRowDirective) rowDirectives!: QueryList<HighlightRowDirective>; // 全选/取消全选逻辑 toggleAllRows(event: Event) { const isChecked = (event.target as HTMLInputElement).checked; // 同步数组中的选中状态 this.levels.forEach(level => level.isSelected = isChecked); // 批量调用指令的setSelected方法 this.rowDirectives.forEach(row => row.setSelected(isChecked)); } // 单行选中切换逻辑 toggleSingleRow(rowDirective: HighlightRowDirective, isSelected: boolean) { rowDirective.setSelected(isSelected); // 同步全选框的状态 const allSelected = this.levels.every(level => level.isSelected); const allCheckbox = document.querySelector('input[name="all"]') as HTMLInputElement; if (allCheckbox) allCheckbox.checked = allSelected; } }
5. 最后别忘了在模块中声明指令
确保你的指令已经在对应的Angular模块里注册:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; // 因为用到了ngModel,必须导入 import { LevelTableComponent } from './level-table.component'; import { HighlightRowDirective } from './highlight-row.directive'; @NgModule({ imports: [BrowserModule, FormsModule], declarations: [LevelTableComponent, HighlightRowDirective], bootstrap: [LevelTableComponent] }) export class AppModule { }
额外说明
- 指令用
@HostListener('click')监听行的点击事件,完全符合Angular的事件监听规范 - 支持自定义高亮类,你可以通过
[highlightClass]="'your-custom-class'"传入自己的样式类 - 实现了行点击、复选框点击的双向联动,全选和单行选中状态保持一致
- 用
Renderer2操作DOM,避免直接操作原生DOM,符合Angular最佳实践
内容的提问来源于stack exchange,提问作者Idris.AH
相关产品推荐
相关产品推荐

