Migrate from DevExtreme
OGE speaks much of DevExtreme's vocabulary — calculateCellValue, lookup, filterRow, headerFilter, load options with skip, take, sort and filter — so a move is mostly renaming nested option objects into flat inputs and dxi-column into oge-column.
component map data grid data sources
Component map
| DevExtreme | OGE |
|---|---|
dx-data-grid | oge-grid · <OgeGrid> |
dx-tree-list | oge-tree-list · <OgeTreeList> |
dx-pivot-grid | oge-pivot-grid · <OgePivotGrid> |
dx-scheduler | oge-scheduler · <OgeScheduler> |
dx-gantt | oge-gantt · <OgeGantt> |
dx-chart · dx-pie-chart | oge-chart · oge-pie-chart |
dx-tree-view | oge-tree-view |
dx-popup | oge-modal (modal) · oge-window (non-modal) |
dx-popover · dx-tooltip | oge-popover · [ogeTooltip] |
dx-toast · notify() | OgeToastService |
dx-context-menu · dx-menu | [ogeContextMenu] · oge-menubar |
dx-button · dx-button-group · dx-drop-down-button | oge-button · oge-button-group · oge-drop-down-button |
dx-select-box · dx-tag-box · dx-autocomplete | oge-select-box · oge-tag-box · oge-autocomplete |
dx-date-box · dx-date-range-box · dx-number-box · dx-text-box | oge-date-box · oge-date-range-box · oge-number-box · oge-text-box |
dx-form | oge-form |
dx-file-uploader | oge-file-uploader |
dx-html-editor | oge-editor |
dx-tabs · dx-tab-panel | oge-tab-strip · oge-tabs |
dx-accordion · dx-drawer · dx-splitter | oge-accordion · oge-drawer · oge-splitter |
Data grid
| DevExtreme | OGE grid |
|---|---|
dataSource | data (an array or a DataSource ) |
keyExpr | keyField |
<dxi-column dataField caption dataType> | <oge-column field caption dataType> |
calculateCellValue · calculateSortValue · calculateFilterExpression | the same names |
lookup: { dataSource, valueExpr, displayExpr } | lookup — the same shape |
cellTemplate ( *dxTemplate ) | *ogeCellTemplate |
filterRow · headerFilter · searchPanel · filterPanel | the same names ( { visible: true } becomes true ) |
groupPanel · grouping · summary.groupItems / totalItems | groupPanel · grouping · groupSummary / totalSummary on the column |
paging · pager | paging: { pageSize, pageSizes } |
selection: { mode } | selectionMode |
editing: { mode, allowUpdating, … } | editing |
scrolling: { mode: 'virtual' } | scrolling: { mode: 'virtual' } |
stateStoring | stateKey (+ OGE_STATE_STORAGE for a custom store) |
columnChooser · allowColumnResizing · allowColumnReordering | columnChooser · columnResize · columnReorder |
onRowClick · onSelectionChanged | (rowClick) · (selectionChanged) |
<!-- DevExtreme -->
<dx-data-grid [dataSource]="orders" keyExpr="id">
<dxo-filter-row [visible]="true" />
<dxo-paging [pageSize]="20" />
<dxi-column dataField="customer" caption="Customer" />
<dxi-column dataField="total" dataType="number" format="currency" />
</dx-data-grid>
<!-- OGE: nested option elements become inputs -->
<oge-grid [data]="orders" keyField="id" [filterRow]="true" [paging]="{ pageSize: 20 }">
<oge-column field="customer" caption="Customer" />
<oge-column field="total" dataType="number" [format]="{ type: 'currency', currency: 'EUR' }" />
</oge-grid>Data sources
A CustomStore with load becomes a CustomDataSource; the load options keep their meaning, and the filter is a typed tree rather than nested arrays (see the filter contract).
// DevExtreme: CustomStore + loadOptions (filter as nested arrays)
const store = new CustomStore({ key: 'id', load: (o) => api.get('/orders', o) });
// OGE: CustomDataSource + LoadOptions (filter as a typed FilterExpr tree)
const orders = new CustomDataSource<Order>({
key: 'id',
load: (options) => api.post('/orders/query', options),
// the header filter's value list
distinct: (field, options) => api.post(`/orders/distinct/${field}`, options),
});Defaults that differ
| Behaviour | DevExtreme | OGE |
|---|---|---|
| Grid paging | on — 20 rows per page | off — set paging: { pageSize: 20 } to keep pages |
| Column resizing | allowColumnResizing = false | columnResize = true |
| Text filter operator | contains | contains — accent- and case-insensitive, Turkish İ / ı included |