Angular:订阅Observable时,AgGrid将不会更新行

时间:2018-08-13 20:36:10

标签: angular rxjs ag-grid

我正在尝试将rxjs和observables合并到ag网格中。为了练习,我遵循一个官方的ag网格示例:https://www.ag-grid.com/javascript-grid-rxjs/

我当前正在使用Angular6。我将js文件更改为ts文件,并进行了适当的更改。我也没有在索引文件中包含任何脚本。每当我调用脚本时,都会遇到一堆MIME错误。所以我将代码转换为严格的角度。我相信这就是造成我问题的原因。 我的目标是让随机行更改其值,而无需在观察到我的更新时刷新网页

在下面的代码中,您将看到基本上有一个间隔函数,该函数选择要显示的随机数。当我运行代码时,所有数据都将加载到我的网格中,但不会刷新或更新。我订阅了可观察到的updates $以输出更新的数据,但是什么也没有发生。这是代码。 onGridReady 函数正在订阅可观察对象。

Component.ts

import { Component, OnInit } from '@angular/core';
import {Model} from '../app/model';
import {Observable} from 'rxjs';
import { HttpClient } from '@angular/common/http';
import {MockServer} from '../app/mockServer'

@Component({
    selector: 'app-root',
    template: 
    `<ag-grid-angular
    #agGrid
    style="width: 1000px; height: 1500px;"
    id="myGrid"
    [rowData]="rowData"
    class="ag-theme-balham"
    [columnDefs]="columnDefs"
    [enableRangeSelection]="true"
    [enableColResize]="true"
    [deltaRowDataMode]="true"
    [getRowNodeId]="getRowNodeId"
    (gridReady)="onGridReady($event)"
    ></ag-grid-angular>
` ,
   styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{

  private gridApi;
  private gridColumnApi;
  private rowData: any[];

  private columnDefs;
  private getRowNodeId;

    constructor() {
      this.columnDefs = [
        {
          headerName: "Code",
          field: "code",
          width: 70
        },
        {
          headerName: "Name",
          field: "name",
          width: 300
        },
        {
          headerName: "Bid",
          field: "bid",
          width: 100,
          cellClass: "cell-number",
          valueFormatter: numberFormatter,
          cellRenderer: "agAnimateShowChangeCellRenderer"
        },
        {
          headerName: "Mid",
          field: "mid",
          width: 100,
          cellClass: "cell-number",
          valueFormatter: numberFormatter,
          cellRenderer: "agAnimateShowChangeCellRenderer"
        },
        {
          headerName: "Ask",
          field: "ask",
          width: 100,
          cellClass: "cell-number",
          valueFormatter: numberFormatter,
          cellRenderer: "agAnimateShowChangeCellRenderer"
        },
        {
          headerName: "Volume",
          field: "volume",
          width: 80,
          cellClass: "cell-number",
          cellRenderer: "agAnimateSlideCellRenderer"
        }
      ];
      this.getRowNodeId = data => data.code;
    }

ngOnInit() {

}

onGridReady(params) {
  this.gridApi = params.api;
  this.gridColumnApi = params.columnApi;


  let mockServer = new MockServer();
  const initialLoad$ = mockServer.initialLoad();
  const updates$ = mockServer.allDataUpdates();
  initialLoad$.subscribe(rowData => {
    params.api.setRowData(rowData);
    updates$.subscribe(newRowData => params.api.setRowData(newRowData));

  });

}

}

function numberFormatter(params) {
  if (typeof params.value === "number") {
    return params.value.toFixed(2);
  } else {
    return params.value;
  }
}

这是服务器类。它包含操作数据的功能。为简便起见,我仅列出无法正常工作的方法。 byRowupdates不能正常工作

byRowupdates() {
        return Observable.create((observer) => {
            const interval = setInterval(() => {
                let changes = [];
                // make some mock changes to the data
                this.makeSomePriceChanges(changes);
                this.makeSomeVolumeChanges(changes);
               // observer.next(changes);
            }, 1000);
            return () => clearInterval(interval);
        });
    }
    // provides randomised data updates to some of the rows
    // only all the row data (with some rows changed)
    allDataUpdates() {
        return Observable.create((observer) => {
            const interval = setInterval(() => {
                let changes = [];
                // make some mock changes to the data
                this.makeSomePriceChanges(changes);
                this.makeSomeVolumeChanges(changes);
                // this time we don't care about the delta changes only
                // this time we return the full data set which has changed rows within it
                //observer.next(_.cloneDeep(this.rowData));
            }, 1000);

            return () => clearInterval(interval);

        });
    }
    /*
     * The rest of the code exists to create or modify mock data
     * it is not important to understand the rest of the example (i.e. the rxjs part of it)
     */
    backfillData(rowData) {
        // the sample data has just name and code, we need to add in dummy figures
        rowData.forEach((dataItem) => {
            // have volume a random between 100 and 10,000
            dataItem.volume = Math.floor((Math.random() * 10000) + 100);
            // have mid random from 20 to 300
            dataItem.mid = (Math.random() * 300) + 20;
            this.setBidAndAsk(dataItem);
        });
        return rowData;
    }
    makeSomeVolumeChanges(changes) {
        for (let i = 0; i < 10; i++) {
            // pick a data item at random
            const index = Math.floor(this.rowData.length * Math.random());
            const currentRowData = this.rowData[index];
            // change by a value between -5 and 5
            const move = (Math.floor(10 * Math.random())) - 5;
            const newValue = currentRowData.volume + move;
            currentRowData.volume = newValue;
            changes.push(currentRowData);
        }
    }
    makeSomePriceChanges(changes) {
        // randomly update data for some rows
        for (let i = 0; i < 10; i++) {
            const index = Math.floor(this.rowData.length * Math.random());
            const currentRowData = this.rowData[index];
            // change by a value between -1 and 2 with one decimal place
            const move = (Math.floor(30 * Math.random())) / 10 - 1;
            const newValue = currentRowData.mid + move;
            currentRowData.mid = newValue;
            this.setBidAndAsk(currentRowData);
            changes.push(currentRowData);
        }
    }
    setBidAndAsk(dataItem) {
        dataItem.bid = dataItem.mid * 0.98;
        dataItem.ask = dataItem.mid * 1.02;
    }
}

我的网格在创建数据时已成功检索数据,但网格未更新新值。我的索引文件中没有任何脚本。这两个课程正在完成所有工作。我对如何正确实现此示例感到非常困惑。谢谢!

1 个答案:

答案 0 :(得分:1)

您期望对网格数据进行数据绑定,但是它不能那样工作。 要更新现有数据,您需要致电

// ...
ObservableList<String> data = FXCollections.observableArrayList(data); //data is List<String>
listView.setItems(data);
  

替换rowNode上的数据。完成后,网格将刷新显示的整个渲染行。

rowNode.setData(data)
  

替换rowNode上指定列的数据。完成后,网格将仅刷新所需行上的渲染单元格。

Check doc for more details

* JFI可以通过数据绑定进行更改,但是您需要通过rowNode.setDataValue(colKey, value) 进行更改并使用node进行操作,但是我不建议您使用这种类型的数据更新。