【问题标题】:How to set selected row programmatically in Kendo Grid + Angular 4?如何在 Kendo Grid + Angular 4 中以编程方式设置选定行?
【发布时间】:2026-01-31 12:40:01
【问题描述】:

我在 Angular 4 + TypeScript + Kendo UI 上有应用程序。我还有一个包含用户表的页面。编辑用户后,我想通过我编辑的 ID 突出显示用户。

users: Observable<Array<User>>;
selectedId: number;    
gridView: GridDataResult;

ngOnInit() {
    this.users = this.route.params
        .switchMap((params: Params) => {
            this.selectedId = +params['id'];
            return this.adminService.getUsers();
        });
    });
}

我还在剑道文档事件中发现了“index”和“selected”字段:

selectionChange(event: SelectionEvent): void {
    //?
}

我尝试在ngOnInit 方法中以编程方式调用selectionChange

this.selectionChange({ index: 1, selected: true });

但我不知道如何在gridView 方法的主体中设置gridView 中的选定行。

那么,我应该如何处理gridView 来选择行?或者可能有一种更简单的方法来按 ID 选择行。

【问题讨论】:

    标签: angular kendo-ui kendo-grid


    【解决方案1】:

    您可以如下手动选择行,我已经在我的剑道网格中尝试过它可以工作,但它可能需要一些抛光。

    定义一些必需的变量:(请在下面的代码中定义缺失的变量)

    rowIndex : number =0;
    isSelectedRowChanged: boolean = false;
    selectedItem : any;
    

    定义函数来设置选中的行如下:

    public SetSelectedRow(index: number, isManualSelection, isSelected, isCellClick) {
    
        var grid = this.el.nativeElement.getElementsByClassName('k-grid-content')[0];
        var rows = grid.getElementsByTagName('tr');
    
        let dataRowIndex = -1;
        let selectedRow = grid.getElementsByClassName('k-state-selected')[0];
        for (let i = 0; i < rows.length; i++) {
            if (rows[i].className.indexOf("k-grouping-row") < 0 && rows[i].className.indexOf("k-group-footer") < 0) {
    
                if (isManualSelection) {
                    this.rowIndex = 1;
    
                    if (selectedRow != null) {
                        selectedRow.className = String(selectedRow.className).replace(" k-state-selected", '').replace("k-state-selected", '');
                    }
                    if (rows[i].className.indexOf("k-state-selected") < 0) {
                        rows[i].click();
                    }
    
                    //Set selectedItem
                    for (let k = 0; k < rows[i].children.length; k++) {
                        if (rows[i].children[k].className.indexOf("k-group-cell") < 0 && rows[i].children[k].children[0] != null) {                            
                            rows[i].children[k].children[0].click();
                            break;
                        }
                    }
                    break;
                } else {
                    if (this.isSelectedRowChanged) {
                        this.rowIndex = index + 1;
                        return;
                    }
                    if (selectedRow == null) {
                        //Set selectedItem
                        rows[i].className = rows[i].className + " k-state-selected";
                        for (let k = 0; k < rows[i].children.length; k++) {
    
                            if (rows[i].children[k].className.indexOf("k-group-cell") < 0 && rows[i].children[k].children[0] != null) {                                
                                rows[i].children[k].children[0].click();
                                break;
                            }
                        }
                        break;
                    }
                    else {
                        dataRowIndex++;
                        if (!this.isSelectedRowChanged) {
                            if (isSelected && !isCellClick) {
                                selectedRow.click();
                            }
    
                            break;
                        } else {
                            this.rowIndex = dataRowIndex + 1;
                        }
                    }
                }
            }
        }       
    }
    

    在将数据源分配给网格后调用下面的函数来设置选择的第一行:

     setTimeout(() => {
            this.rowIndex = 0;
            this.SetSelectedRow(0, true, false, false);
        }, 200);
    

    行选择更改事件上编写以下函数:

     public OnSelection_Changed(item: any): void {
        if (!item.selected) {
            this.SetSelectedRow(item.index, false, true, false);
        }
        else {
            this.SetSelectedRow(item.index, false, false, false);
        }        
    }
    

    同时定义单元格点击事件

    OnCellClick(dataItem, rowIndex, columnIndex) { 
        if (this.selectedItem != dataItem) {
            this.isSelectedRowChanged = true;
            this.selectedItem = dataItem;            
        }
        else {
            this.isSelectedRowChanged = false;
        }
    }
    

    【讨论】:

      【解决方案2】:

      我的临时解决方案是:

      在html中插入属性data-id

      <kendo-grid-column title="Actions">
          <ng-template kendoGridCellTemplate let-user>
              <div class="btn-group">
                  <button class="btn btn-xs btn-default" type="button" data-toggle="tooltip" title="Edit User" [attr.data-id]="user.id"><i class="fa fa-pencil"></i></button>
              </div>
          </ng-template>
      </kendo-grid-column>
      

      在ts中:

      gridView: GridDataResult;
      selectedId: number;
      
      constructor(private route: ActivatedRoute,
          private adminService: AdminService) { }
      
      ngOnInit() {
          this.route.params
              .switchMap((params: Params) => {
                  this.selectedId = +params['id'];
                  return this.adminService.getUsers();
              })
              .subscribe((response: GridDataResult) => {
                  this.gridView = response;
                  this.selectRow();
              });
      }
      
      
      selectRow() {
          setTimeout(() => {
              if (this.selectedId) {
                  let button = document.querySelector('[data-id="' + this.selectedId + '"]');
                  if (button) {
                      let tr = button.parentElement.parentElement.parentElement;
                      tr.className += " k-state-selected";
                  }
              }
          }, 200);
      }
      

      【讨论】: