You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 07:54:04