AngularJS新手求助:如何实现类Jira的表格列过滤指令
嘿,作为AngularJS老玩家,刚好帮你搞定这个列过滤指令!完全理解你要做类似Jira的列过滤功能——每列表头加个按钮,点了弹输入框,输入后过滤对应列。我给你一步步拆解实现,代码都是新手友好型的,注释也写清楚了~
核心思路
我们要做一个可复用的指令,绑定到表格的<th>标签上:
- 指令负责渲染列名、过滤按钮和输入框
- 输入框的值双向绑定到父控制器的过滤条件对象
- 表格数据通过自定义过滤函数,根据各列的过滤条件筛选内容
具体代码实现
1. 定义指令和控制器
先创建AngularJS模块,然后写columnFilter指令和表格控制器:
angular.module('columnFilterApp', []) // 列过滤指令 .directive('columnFilter', function() { return { restrict: 'A', // 作为属性使用 scope: { columnLabel: '@columnFilter', // 显示的列名(比如"姓名") columnKey: '@', // 对应数据对象的属性键(比如"name") filterModel: '=' // 双向绑定到父scope的过滤值 }, template: ` <div class="header-wrapper"> <span>{{columnLabel}}</span> <button class="filter-btn" ng-click="toggleFilter()">🔍</button> <input class="filter-input" ng-show="isFilterVisible" ng-model="filterModel" placeholder="过滤{{columnLabel}}" ng-blur="isFilterVisible = false" ng-keyup="$event.keyCode === 13 && (isFilterVisible = false)" > </div> `, link: function(scope) { // 初始化输入框显示状态 scope.isFilterVisible = false; // 切换输入框显示/隐藏 scope.toggleFilter = function() { scope.isFilterVisible = !scope.isFilterVisible; // 显示时自动聚焦输入框(可选优化) if (scope.isFilterVisible) { setTimeout(() => { document.querySelector(`input[ng-model="filterModel"]`).focus(); }, 0); } }; } }; }) // 表格控制器 .controller('TableCtrl', function($scope) { // 示例表格数据(替换成你的实际数据) $scope.tableData = [ { name: '张三', age: 28, dept: '前端' }, { name: '李四', age: 32, dept: '后端' }, { name: '王五', age: 25, dept: '产品' }, { name: '赵六', age: 30, dept: '前端' }, { name: '孙七', age: 26, dept: '设计' } ]; // 存储各列的过滤条件:键是数据属性名,值是用户输入的文本 $scope.filters = {}; // 自定义过滤函数,供ng-repeat使用 $scope.filterRows = function(row) { // 遍历所有有过滤值的列 for (let key in $scope.filters) { const filterText = $scope.filters[key].trim(); if (!filterText) continue; // 空值跳过 // 把值转成字符串,不区分大小写匹配 const rowValue = String(row[key]).toLowerCase(); const filterValue = filterText.toLowerCase(); // 如果当前行的该列不包含过滤文本,就过滤掉这行 if (!rowValue.includes(filterValue)) { return false; } } // 所有过滤条件都满足,保留该行 return true; }; });
2. HTML结构
把指令绑定到表头,表格数据用ng-repeat配合自定义过滤函数:
<div ng-app="columnFilterApp" ng-controller="TableCtrl"> <table class="data-table"> <thead> <tr> <!-- 绑定指令:column-filter是显示的列名,column-key是数据属性名,filter-model绑定过滤值 --> <th column-filter="姓名" column-key="name" filter-model="filters.name"></th> <th column-filter="年龄" column-key="age" filter-model="filters.age"></th> <th column-filter="部门" column-key="dept" filter-model="filters.dept"></th> </tr> </thead> <tbody> <tr ng-repeat="row in tableData | filter:filterRows"> <td>{{row.name}}</td> <td>{{row.age}}</td> <td>{{row.dept}}</td> </tr> </tbody> </table> </div>
3. 基础样式(可选)
给表头和输入框加一点样式,让界面更友好:
.data-table { border-collapse: collapse; width: 100%; margin-top: 20px; } .data-table th, .data-table td { border: 1px solid #ddd; padding: 8px; text-align: left; } .data-table th { background-color: #f5f5f5; } .header-wrapper { display: flex; align-items: center; gap: 6px; } .filter-btn { background: none; border: none; cursor: pointer; font-size: 14px; } .filter-input { padding: 3px 6px; font-size: 12px; border: 1px solid #ccc; border-radius: 3px; }
关键细节说明
- 双向绑定:指令通过
filterModel: '='把输入框的值同步到父控制器的filters对象,这样过滤条件能实时生效 - 不区分大小写匹配:过滤函数里把行值和过滤文本都转成小写,用户输入时不用在意大小写
- 交互优化:输入框失去焦点或按回车会自动隐藏,点击按钮切换显示,还加了自动聚焦的小功能
- 可复用性:只要给
<th>加指令,指定列名和数据属性键,就能给任意列加上过滤功能,完全符合你的需求
如果需要调整过滤规则(比如精确匹配、数字范围过滤),只需要修改filterRows函数里的判断逻辑就行~
内容的提问来源于stack exchange,提问作者kishoresrivatsa
相关产品推荐
相关产品推荐

