Angular: AgGrid не будет обновлять строки при подписке на Observable

Я пытаюсь включить rxjs и наблюдаемые в сетку ag. Для практики я следую официальному примеру сетки ag: https://www.ag-grid.com/javascript-grid-rxjs/

В настоящее время я использую Angular 6. Я изменил файл js на файл ts и внес соответствующие изменения. Я также не включаю никаких скриптов в свой индексный файл. Каждый раз при вызове скрипта я получал кучу ошибок MIME. Поэтому я преобразовал код в строго угловой. Я считаю, что это причина моей проблемы. Моя цель состоит в том, чтобы случайные строки меняли свои значения без необходимости обновлять веб-страницу, когда я подписываюсь на мои наблюдаемые обновления

В приведенном ниже коде вы увидите, что в основном есть функция интервала, которая выбирает случайные числа для отображения. Когда я запускаю свой код, все данные загружаются в мою сетку, но не обновляются и не обновляются. Я подписываюсь на обновления $ observable для вывода обновленных данных, но ничего не происходит. Вот код. Функция 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;
    }
}

Моя сетка успешно получает данные при создании, но сетка не обновляет новые значения. В моем индексном файле нет скриптов. Эти два класса делают всю работу. Я очень не понимаю, как правильно реализовать этот пример. Спасибо!


person John    schedule 13.08.2018    source источник


Ответы (1)


Вы ожидаете привязки данных для данных сетки, но это не работает. Для обновления имеющихся данных вам необходимо позвонить

rowNode.setData(data)

Заменяет данные в rowNode. По завершении сетка обновит всю отображаемую строку, если она отображается.

or

rowNode.setDataValue(colKey, value)

Заменяет данные в rowNode для указанного столбца. По завершении сетка обновит отображаемую ячейку только в требуемой строке.

Подробнее см. в документе

* Возможно изменение JFI через привязку данных, но вам потребуется сделать это через node и манипулировать с помощью node.data, но я не рекомендую использовать этот тип обновления данных.

person un.spike    schedule 27.08.2018
comment
В моем тесте rowNode.setData(data) обновил rowNode.data, но не обновил gridOptions.rowData и внес несогласованность. - person zipper; 26.08.2019