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

Angular KendoGrid新增行后拖拽排序失效问题求助

问题:Kendo Grid动态新增行后行重排功能异常

在Angular项目中使用带数据源的Kendo Grid,已设置rowReorderable=true开启行重排。网格加载完成后,初始行可正常拖拽调整顺序,但动态新增行后,无法将其他行拖拽到新增行的位置,仅能在最初的几行上操作。

已在测试示例中通过this.gridData = [...this.gridData, ...samplecustomers]的方式修复,但该方案在主项目中无效。主项目相关代码如下:

组件逻辑代码

openTagSelectionPopup() {
    this.popupService.showEntitySelectionPopup<BaseTag>({
        title: this.translate.get('i18n:LABEL.TAG_SELECTION'),
        entitySet: 'UserBaseTags',
        singleEntitySet: 'BaseTags',
        includes: 'Asset.AssetType,MeasurementUnit.Measurement',
        sort: [{ field: 'Asset.Path', dir: 'asc' }, { field: 'Name', dir: 'asc' }],
        multiSelect: true,
        selectionRequired: false,
        columns: [
            { field: 'Asset.Path', title: this.translate.get('i18n:TAG.ASSET'), filterable: true },
            { field: 'Name', title: this.translate.get('i18n:TAG.NAME'), filterable: true },
            { field: 'MeasurementUnit.Name', title: this.translate.get('i18n:TAG.MEASUREMENT_UNIT'), filterable: true },
            { field: 'MeasurementUnit.Symbol', title: this.translate.get('i18n:TAG.MEASUREMENT_UNIT.SYMBOL'), filterable: true }
        ]
    }).subscribe({
        next: result => {
            if (result && result.length) {
                let addedItems: DataSourceProductionConsumptionItemTag[] = [];
                result.forEach((tag: BaseTag) => {
                    if (findIndex(this.items, (item: DataSourceProductionConsumptionItemTag) => item.TagId == tag.Id) == -1) {
                        addedItems.push({
                            TagId: tag.Id,
                            Tag: tag,
                            Category: '',
                            Color: '#000000'
                        });
                    }
                });
                this.items = [...this.items, ...addedItems];
            }
        }
    });
}

模板代码

<kendo-grid #itemsGrid [kendoGridBinding]="items" [height]="410"  style="margin-bottom: 16px;" [rowReorderable]="true"
    kendoGridSelectBy="TagId" [(selectedKeys)]="selectedItemKeys" 
    (cellClick)="cellClick($event)" (cellClose)="cellClose($event)">
    <ng-template kendoGridToolbarTemplate>
        <button kendoButton look="outline" (click)="openTagSelectionPopup()">{{ 'i18n:DATASOURCE.TAGS.ADD' |
            translate }}</button>
        <button kendoButton look="outline" [disabled]="selectedItemKeys.length === 0"
            (click)="removeItems()">{{ 'i18n:DATASOURCE.TAGS.REMOVE' | translate }}</button>
        <kendo-formerror *ngIf="hasGridErr()">{{gridErr}}</kendo-formerror>
    </ng-template>
    <kendo-grid-rowreorder-column [width]="40"></kendo-grid-rowreorder-column>

    <kendo-grid-column [title]="translate.get('i18n:DATASOURCE.PRODUCTION_CONSUMPTION.TAG')" [field]="'TagId'">
        <ng-template kendoGridCellTemplate let-dataItem let-rowIndex>
            {{ getTagDescription(dataItem) }}
        </ng-template>
    </kendo-grid-column>
</kendo-grid>    

新增行后UI显示正常,但拖拽功能仍存在异常。


解决方案

1. 设置TrackBy函数

Kendo Grid的默认变更检测可能无法正确识别新增行的唯一性,添加trackBy指令帮助Grid精准跟踪行数据的变化:

<kendo-grid #itemsGrid [kendoGridBinding]="items" [trackBy]="trackByTagId" ...>

在组件中实现对应的跟踪函数:

trackByTagId(index: number, item: DataSourceProductionConsumptionItemTag): number {
    return item.TagId; // 基于唯一标识TagId跟踪行
}

2. 手动触发Grid刷新

新增行后,强制Grid重新渲染并绑定拖拽事件,通过ViewChild获取Grid实例并调用refresh():

import { Component, ViewChild } from '@angular/core';
import { GridComponent } from '@progress/kendo-angular-grid';

@Component({/* 组件元数据 */})
export class YourComponent {
    @ViewChild('itemsGrid') itemsGrid: GridComponent;

    openTagSelectionPopup() {
        // ... 原有弹窗逻辑
        this.items = [...this.items, ...addedItems];
        // 等待DOM更新后执行刷新
        setTimeout(() => {
            this.itemsGrid.refresh();
        });
    }
}

3. 切换为Observable数据源

改用BehaviorSubject作为数据源,让Grid自动感知数据变化并更新行重排绑定:

import { BehaviorSubject } from 'rxjs';

export class YourComponent {
    private itemsSubject = new BehaviorSubject<DataSourceProductionConsumptionItemTag[]>([]);
    items$ = this.itemsSubject.asObservable();

    // 初始化时传入初始数据
    ngOnInit() {
        this.itemsSubject.next(yourInitialItems);
    }

    openTagSelectionPopup() {
        // ... 原有弹窗逻辑
        const updatedItems = [...this.itemsSubject.value, ...addedItems];
        this.itemsSubject.next(updatedItems);
    }
}

模板中绑定Observable数据源:

<kendo-grid #itemsGrid [data]="items$" ...>

4. 检查行重排列的有效性

确保kendo-grid-rowreorder-column已正确添加到Grid模板中,没有被自定义样式或其他模板元素覆盖拖拽手柄的事件绑定。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:35:16