Angular: AgGrid 在订阅 Observable 时不会更新行
Angular: AgGrid will not update rows when subscribing to Observable
我正在尝试将 rxjs 和 observables 合并到 ag 网格中。作为练习,我遵循官方的 ag 网格示例:https://www.ag-grid.com/javascript-grid-rxjs/
我目前正在使用Angular 6.我把js文件改成了ts文件,并做了相应的修改。我的索引文件中也不包含任何脚本。每当我调用脚本时,我都会收到一堆 MIME 错误。所以我转换为代码严格angular。我相信这是导致我的问题的原因。
我的目标是让随机行更改它们的值,而无需在订阅我的可观察更新时刷新网页
在下面的代码中,您将看到基本上有一个间隔函数,用于选择要显示的随机数。当我 运行 我的代码时,所有数据都加载到我的网格中,但它不会刷新或更新。我订阅了 updates$ 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;
}
}
这是服务器class。这包含操作数据的函数。为简洁起见,我只包括无法正常工作的方法。 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;
}
}
我的网格在创建时成功检索了数据,但网格没有更新新值。我的索引文件中没有任何脚本。这两个 classes 正在做所有的工作。我对如何正确实施这个例子感到很困惑。谢谢!
您期待网格数据的数据绑定,但它不是那样工作的。
要更新现有数据,您需要调用
rowNode.setData(data)
Replaces the data on the rowNode. When complete, the grid will refresh the the entire rendered row if it is showing.
或
rowNode.setDataValue(colKey, value)
Replaces the data on the rowNode for the specified column. When complete, the grid will refresh the rendered cell on the required row only.
*JFI 可以通过数据绑定进行更改,但您需要通过 node
进行更改并使用 node.data
进行操作,但我不建议使用这种类型的数据更新。
我正在尝试将 rxjs 和 observables 合并到 ag 网格中。作为练习,我遵循官方的 ag 网格示例:https://www.ag-grid.com/javascript-grid-rxjs/
我目前正在使用Angular 6.我把js文件改成了ts文件,并做了相应的修改。我的索引文件中也不包含任何脚本。每当我调用脚本时,我都会收到一堆 MIME 错误。所以我转换为代码严格angular。我相信这是导致我的问题的原因。 我的目标是让随机行更改它们的值,而无需在订阅我的可观察更新时刷新网页
在下面的代码中,您将看到基本上有一个间隔函数,用于选择要显示的随机数。当我 运行 我的代码时,所有数据都加载到我的网格中,但它不会刷新或更新。我订阅了 updates$ 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;
}
}
这是服务器class。这包含操作数据的函数。为简洁起见,我只包括无法正常工作的方法。 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;
}
}
我的网格在创建时成功检索了数据,但网格没有更新新值。我的索引文件中没有任何脚本。这两个 classes 正在做所有的工作。我对如何正确实施这个例子感到很困惑。谢谢!
您期待网格数据的数据绑定,但它不是那样工作的。 要更新现有数据,您需要调用
rowNode.setData(data)
Replaces the data on the rowNode. When complete, the grid will refresh the the entire rendered row if it is showing.
或
rowNode.setDataValue(colKey, value)
Replaces the data on the rowNode for the specified column. When complete, the grid will refresh the rendered cell on the required row only.
*JFI 可以通过数据绑定进行更改,但您需要通过 node
进行更改并使用 node.data
进行操作,但我不建议使用这种类型的数据更新。