【问题标题】:Programmatically select a row ag-grid + angular 2以编程方式选择一行 ag-grid + angular 2
【发布时间】:2018-01-23 19:08:55
【问题描述】:

尝试在 ag-grid 中默认选择第一行。根据 ag-grid 文档,我应该可以使用 NodeSelection Api(https://www.ag-grid.com/javascript-grid-selection/?framework=all#gsc.tab=0) 来做到这一点。但我根本无法到达节点对象。 HTML 文件

<div class="pulldown panel panel-default">
          <div class="panel-heading">{{rulesSummaryTitle}}</div>
          <ag-grid-angular #agGrid   class="ag-fresh ag-bootstrap"
                           [gridOptions]="gridOptions"
                           [rowData]="rowData"
                           [columnDefs]="columnDefs"
                           [enableSorting]="true"
                           rowSelection="single"
                           [pagination]="true"
                           [suppressCellSelection]="true"
                           (gridReady)="onGridReady($event)"
                           (rowSelected)="onRowSelect($event)">
          </ag-grid-angular>
      </div>

我在“onGridReady”方法中调用节点选择 api,但出现错误消息“无法在未定义时调用 setSelected”。

public onGridReady(event: any): void {
    event.api.sizeColumnsToFit();
    this.gridOptions.api.node.setSelected(true);
  }

【问题讨论】:

    标签: angular ag-grid


    【解决方案1】:

    gridOptions.api 对象上没有 node 属性。你会想做更多这样的事情:

    public onGridReady(event: any): void {
      event.api.sizeColumnsToFit();
      gridOptions.api.forEachNode(node=> node.rowIndex ? 0 : node.setSelected(true))
    }
    

    这将检查数据中的每个节点,看看rowIndex是否为0,当为0时,它使用节点对象来设置选定的属性

    【讨论】:

    • 添加 "gridOptions.api.forEachNode(node=> node.rowIndex ? 0 : node.setSelected(true))" 没有行为改变,我没有看到任何错误,也没有第一行被选中。
    • 为了验证是否存在任何节点,我对代码进行了以下更改 this.gridOptions.api.forEachNode( (node) => { let nodeTemp = node; console.log("node selected : " + nodeTemp); });但看到控制台语句从未被执行。话虽如此,我确实看到两行显示数据。我不明白为什么没有节点。
    • 完美答案。这就是我要找的。​​span>
    【解决方案2】:

    尝试使用 gridOptions.api.setFocusedCell(0, [column name]) 其中列名可以是可见列

    【讨论】:

      【解决方案3】:

      找到解决方案,问题是在从 Observables 填充行数据之前调用“onGridReady”函数。所以实际上没有选择语句可以选择的行。

      import { Component } from '@angular/core';
      import {Observable} from "rxjs/Observable";
      export class Hero {
        id: number;
        name: string;
      }
      
      @Component({
        selector: 'my-app',
        template: `
          <ag-grid-angular style="width: 500px; height: 115px;" class="ag-fresh"
                       [rowData]="rowData"
                       (gridReady)="onReady($event)"
                       [columnDefs]="columnDefs">
      </ag-grid-angular>
      <ag-grid-angular style="width: 500px; height: 115px;" class="ag-fresh"
                       [rowData]="rowData2"
                       (gridReady)="onReady($event)"
                       [columnDefs]="columnDefs">
      </ag-grid-angular>
      <ag-grid-angular style="width: 500px; height: 115px;" class="ag-fresh"
                       [gridOptions]="gridOptions"
                       [rowData]="rowData3"
                       (gridReady)="onReady($event)"
                       (rowDataChanged)="onRowDataChanged()"
                       [columnDefs]="columnDefs">
      </ag-grid-angular>
          `
      })
      export class AppComponent {
          columnDefs;
          rowData;
          rowData2;
          rowData3;
      
          constructor() {
            this.gridOptions = {
            rowData: this.rowData3
          };
            console.log("in here");
            console.log("in here");
            console.log("in here");
              this.columnDefs = [
                  {headerName: "Make", field: "make"},
                  {headerName: "Model", field: "model"},
                  {headerName: "Price", field: "price"}
              ];
      
              this.rowData = [
                  {make: "Toyota", model: "Celica", price: 35000},
                  {make: "Ford", model: "Mondeo", price: 32000},
                  {make: "Porsche", model: "Boxter", price: 72000}
              ]
      
              let val = [
            {make: "Toyota", model: "Celica", price: 35000},
            {make: "Ford", model: "Mondeo", price: 32000},
            {make: "Porsche", model: "Boxter", price: 72000}
          ];
      
      
          let res : Observable<any> = Observable.create(observer => {
            setTimeout(()=>{
              observer.next(val);
            },1);
          });
          res.subscribe(
            resposne => {
              this.rowData2 = resposne;
            });
      
            let res1 : Observable<any> = Observable.create(observer => {
            setTimeout(()=>{
              observer.next(val);
            },2000);
          });
          res1.subscribe(
            resposne => {
              this.rowData3 = resposne;
            });
      
      
          }
             /**
         * Select the first row as default...
         */
        public onRowDataChanged(): void {
          this.gridOptions.api.forEachNode(node => node.rowIndex ? 0 : node.setSelected(true));
        }
      
      
          private onReady(params) {
              params.api.sizeColumnsToFit();
             params.api.forEachNode(node => node.rowIndex ? 0 : node.setSelected(true));
          }
      }
      

      https://plnkr.co/edit/PSKnSjAo6omDAo5bjm1J.

      添加了带有三个 ag-grid 的 plunker。第一个网格具有预定义的行数据值,第二个网格具有从可观察对象填充的行数据,但延迟非常小,第三个网格具有从具有较高延迟的可观察对象填充的行数据值。如果第一个和第二个“onGridReady”函数被调用并且第一行被选中,但在第三个网格的情况下,我们必须为“rowDataChanged”事件提供选择行语句以选择行。

      【讨论】:

      • 谢谢,您的回答有帮助。我不得不做类似的事情: setTimeout(() => { /* select nodes using api */ }, 1);
      【解决方案4】:

      在 onGridReady 上,您可以使用此代码默认选择第一行。

      let  rowIndex = 0;
      this.GridOptions.api.paginationGoToFirstPage(); // If pagination is implemented
      this.GridOptions.api.selectIndex(rowIndex, false, false);
      this.GridOptions.api.setFocusedCell(0, "FirstName");
      

      【讨论】:

      • selectIndex 已弃用 => 控制台警告:不要使用 api 进行选择,而是调用 node.setSelected(value)
      【解决方案5】:

      agrid on ready 函数不适用于此事务。如果您想在 ag 准备好之前处理您必须接近的数据,agon 就准备好了。但是没有这个选项。如果你在你的方法中添加这个代码。

      getProducts: async function() {
            let data = await repository.getAll("Product").then(r => r.list);
            for (let i = 0; i < this.value.length; i++) {
              for (let j = 0; j < data.length; j++) {
                if (this.value[i].productId == data[j].productId) {
                  let x = data.splice(j, 1)[0];
                  data.unshift(x);
                  break;
                }
              }
            }
            this.productDataForAggrid = data;
            this.gridApi.setRowData(this.productDataForAggrid);
            window.watcher = setInterval(this.setSelectedItems, 50, this.gridApi);
          }
      

      这个函数是正常的get方法,除了最后一部分。如果您在 ag 上选择了一些行并且如果您关闭 ag,则所有选择都将在表格中删除,但是当您再次打开 ag 时,您仍然可以在数据属性中选择哪些数据。您将以这种方式闲置。这部分代码用于真正的就绪功能,我的意思是在准备数据之前。

      setSelectedItems(api) {
            if (this.productDataForAggrid.length == api.getDisplayedRowCount()) {
              for (let i = 0; i < this.value.length; i++) {
                let node = api.getRowNode(this.value[i].productId.toString());
                if (node) {
                  node.setSelected(true);
                }
              }
              this.gridApi.sizeColumnsToFit();
              clearInterval(window.watcher);
              window.watcher = 0;
              //console.log("ready!");
            }
          }
      

      首先,我们将在 value 道具上添加所有选定的数据,以添加到帐单列表中。但是,如果客户想重新打开产品,请再次选择 aggrid,客户无法看到所选产品。此 getproducts 功能适用于每次打开 ag 时。并获得所有产品。将此数据与我们的 value 属性进行比较。并发送到 setSelectedItems 功能进行检查。

      
       saveSelectedProducts() {
            this.value.splice(0, this.value.length);
            for (var i = 0; i < this.gridOptions.api.getSelectedRows().length; i++) {
              if (this.gridOptions.api.getSelectedRows()[i].sellPrice === undefined)
                this.gridOptions.api.getSelectedRows()[
                  i
                ].sellPrice = this.gridOptions.api.getSelectedRows()[i].odooId;
      
              if (this.gridOptions.api.getSelectedRows()[i].piece === undefined)
                this.gridOptions.api.getSelectedRows()[i].piece = 1;
      
              this.value.push(this.gridOptions.api.getSelectedRows()[i]);
            }
            //this.$emit("selectedProductsList", this.value);
            this.openProductPopup = false;
          },
      

      【讨论】:

        【解决方案6】:

        我们需要调用setSelected(true)方法来选择行节点。主要问题是获取行节点。

        我们可以通过调用getRenderedNodes() 方法获取行节点。根据the doc

        检索渲染节点。由于虚拟化,这将仅包含当前可见行和缓冲区中的行。

        因此,我们将获得getRenderedNodes() 方法返回的数组的索引0 处的第一行节点。实现将如下-

        public onGridReady(event: any): void {
          let nodes = event.api.getRenderedNodes();
          if (nodes.length) {
            nodes[0].setSelected(true); //selects the first row in the rendered view
          }
        }
        

        这是工作的 plunker 演示:https://plnkr.co/edit/J40sUeDSwyDEi76X

        【讨论】:

          【解决方案7】:

          setSelected(false) 可以在 (selectionChanged) 事件上调用。

          在 ag grid 公共方法中可用的网格事件之一

          【讨论】:

            猜你喜欢
            • 2020-11-08
            • 1970-01-01
            • 2019-03-21
            • 2017-03-03
            • 2018-02-14
            • 2020-02-08
            • 2021-06-07
            • 1970-01-01
            • 2018-10-26
            相关资源
            最近更新 更多