Kotlin/JS TableData数据类如何添加表格列升降序箭头标识
完全可行,核心是需要在存储排序字段的同时,记录每个字段的排序方向(升序/降序),同时对外暴露查询当前列排序状态的方法供前端渲染箭头,具体实现如下:
步骤1:定义排序键封装类
新增数据类同时存储排序字段和排序方向:
// 排序键:封装排序字段和排序方向 data class SortKey<T : Any>( val property: KProperty1<T, Comparable<*>>, val isAsc: Boolean = true // 默认首次点击为升序 )
步骤2:改造TableData核心类
替换原有字段存储逻辑,更新排序规则,新增排序状态查询接口:
data class TableData<T : Any>( var items: List<T>, // 存储排序规则列表,优先级按列表顺序从高到低 private val sortRules: MutableList<SortKey<T>> = mutableListOf(), ) : Iterable<T> { override fun iterator() = items.iterator() /** * 处理排序请求 * @param incoming 点击的排序字段 * @param singleSort 为true时仅保留当前字段排序(主流表格默认单列排序),为false时支持多列累加排序 */ fun handleSortRequest(incoming: KProperty1<T, Comparable<*>>, singleSort: Boolean = true) { if (singleSort) { // 单列排序逻辑:首次点击升序,再次点击翻转方向 val existing = sortRules.firstOrNull { it.property == incoming } sortRules.clear() sortRules.add( if (existing == null) SortKey(incoming, isAsc = true) else SortKey(incoming, isAsc = !existing.isAsc) ) // 如果需要支持第三次点击取消排序,可在这里加判断:如果existing存在且翻转后需要取消,直接清空sortRules即可 } else { // 多列排序逻辑(适配按住Shift点击多字段排序的场景) val existingIndex = sortRules.indexOfFirst { it.property == incoming } if (existingIndex >= 0) { val oldRule = sortRules[existingIndex] sortRules[existingIndex] = oldRule.copy(isAsc = !oldRule.isAsc) } else { sortRules.add(SortKey(incoming, isAsc = true)) } } // 构建多规则排序器 var comparator = if (sortRules.first().isAsc) { compareBy(sortRules.first().property) } else { compareByDescending(sortRules.first().property) } sortRules.drop(1).forEach { rule -> comparator = if (rule.isAsc) comparator.thenBy(rule.property) else comparator.thenByDescending(rule.property) } // 执行排序 items = items.sortedWith(comparator) } /** * 查询指定列的排序状态 * @return 1=升序,-1=降序,0=未参与排序 */ fun getSortDirection(property: KProperty1<T, Comparable<*>>): Int { val rule = sortRules.firstOrNull { it.property == property } ?: return 0 return if (rule.isAsc) 1 else -1 } }
步骤3:Kotlin/JS前端渲染箭头示例
渲染表头时调用getSortDirection方法判断显示的箭头标识即可,以kotlinx.html渲染为例:
thead { tr { // 卡路里列示例 th { +"卡路里" span { when(tableData.getSortDirection(Meal::calories)) { 1 -> +" ↑" -1 -> +" ↓" else -> +"" } } onClick { tableData.handleSortRequest(Meal::calories) // 触发表格重新渲染逻辑 } } // 其他列分别绑定 Meal::salad、Meal::mainCourse、Meal::desert 即可 } }
使用测试示例
// 初始化表格数据 val tableData = TableData(mealList) // 第一次点击卡路里列:升序,显示↑ tableData.handleSortRequest(Meal::calories) println(tableData.getSortDirection(Meal::calories)) // 输出1 // 第二次点击卡路里列:降序,显示↓ tableData.handleSortRequest(Meal::calories) println(tableData.getSortDirection(Meal::calories)) // 输出-1
内容的提问来源于stack exchange,提问作者Chris Legge
相关产品推荐
相关产品推荐

