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

Yii2 Kartik可展开列如何仅在展开时加载数据?

实现Kartik Expandable Column点击展开时懒加载子数据

要解决预加载所有子数据导致的性能问题,你可以通过懒加载的方式,仅在用户点击展开按钮时才请求对应行的子数据,具体实现步骤如下:

1. 配置网格的ExpandableColumn

初始化网格时,关闭默认的预加载逻辑,绑定自定义的点击事件:

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        // 其他业务列...
        [
            'class' => '\kartik\grid\ExpandableColumn',
            'value' => fn($model) => GridView::ROW_COLLAPSED, // 默认保持折叠状态
            'detailUrl' => false, // 禁用组件默认的自动加载逻辑
            'toggleButton' => [
                'onclick' => "loadChildData({$model->id}, this)", // 传递当前行主键和按钮元素
            ],
        ],
    ],
]); ?>

2. 编写前端AJAX加载逻辑

添加JS函数处理点击事件,请求后端接口并渲染子数据:

function loadChildData(parentId, toggleBtn) {
    const $row = $(toggleBtn).closest('tr');
    const $detailRow = $row.next('.kv-expandable-row');

    // 避免重复加载已获取的数据
    if ($detailRow.length && $detailRow.html().trim()) {
        return;
    }

    // 插入加载提示
    const colCount = $row.find('td').length;
    $row.after(`<tr class="kv-expandable-row"><td colspan="${colCount}"><div class="text-center py-3">加载中...</div></td></tr>`);

    // 发起AJAX请求
    $.ajax({
        url: '/your-controller/load-child-data', // 替换为你的后端接口地址
        type: 'GET',
        data: { parent_id: parentId },
        success: (htmlContent) => {
            // 替换加载提示为子数据内容
            $row.next('.kv-expandable-row').find('td').html(htmlContent);
        },
        error: () => {
            $row.next('.kv-expandable-row').find('td').html('<div class="text-danger py-3">加载失败,请重试</div>');
        }
    });
}

3. 后端编写数据接口

创建控制器方法,根据主键查询子数据并返回渲染后的HTML:

// Yii2 控制器示例
public function actionLoadChildData($parent_id) {
    // 根据父ID查询子数据
    $childModels = ChildModel::find()
        ->where(['parent_id' => $parent_id])
        ->all();

    // 渲染子数据视图(可以是小型GridView或自定义HTML)
    return $this->renderPartial('_child_content', [
        'childModels' => $childModels,
    ]);
}

4. 子数据视图示例(_child_content.php)

可以用简单的表格或GridView展示子数据:

<div class="table-responsive">
    <table class="table table-sm table-striped">
        <thead>
            <tr>
                <th>子数据ID</th>
                <th>名称</th>
                <th>详情</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($childModels as $model): ?>
                <tr>
                    <td><?= $model->id ?></td>
                    <td><?= $model->name ?></td>
                    <td><?= $model->detail ?></td>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</div>

注意事项

  • 确保主数据行的主键唯一且能正确关联子数据。
  • 可以添加防抖逻辑,防止用户频繁点击触发多次请求。
  • 子数据视图可以根据业务需求自定义,不一定局限于表格形式。

内容的提问来源于stack exchange,提问作者Karijoatmo Sergio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 03:48:35