Skip to content

Commit 095bab7

Browse files
authored
TreeList: Fix navigation to the required node when cellRender is specified (T1275775) (DevExpress#29558)
1 parent e0697ea commit 095bab7

11 files changed

+117
-4
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import TreeList from 'devextreme-testcafe-models/treeList';
2+
import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
3+
import url from '../../helpers/getPageUrl';
4+
import { createWidget } from '../../helpers/createWidget';
5+
6+
fixture`Public methods`
7+
.page(url(__dirname, '../container.html'));
8+
9+
const getItems = (): Record<string, unknown>[] => {
10+
const items: Record<string, unknown>[] = [];
11+
12+
for (let i = 0; i < 100; i += 1) {
13+
items.push({ key: `item_${i}`, parentKey: null });
14+
15+
for (let j = 0; j < 100; j += 1) {
16+
items.push({ key: `item_${i}_${j}`, parentKey: `item_${i}` });
17+
}
18+
}
19+
20+
return items;
21+
};
22+
23+
[true, false].forEach((renderAsync) => {
24+
[true, false].forEach((useNativeScrolling) => {
25+
test(`The renderAsync=${renderAsync} and scrolling.useNative=${useNativeScrolling}: The navigateToRow method should work correctly when there are asynchronous cell templates and virtual scrolling is enabled (T1275775)`, async (t) => {
26+
// arrange
27+
const treeList = new TreeList('#container');
28+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
29+
30+
await t
31+
.expect(treeList.getDataCell(0, 0).element.textContent)
32+
.contains('item_');
33+
34+
// act
35+
await treeList.apiNavigateToRow('item_80_50');
36+
37+
// assert
38+
await t
39+
.expect(treeList.getDataCell(131, 0).element.textContent)
40+
.contains('item_');
41+
42+
await takeScreenshot(`T1275775-navigateToRow-with-async-cell-templates_(renderAsync=${renderAsync}_useNativeScrolling=${useNativeScrolling})`, treeList.element);
43+
44+
await t
45+
.expect(compareResults.isValid())
46+
.ok(compareResults.errorMessages());
47+
}).before(async () => createWidget('dxTreeList', {
48+
dataSource: getItems(),
49+
height: 500,
50+
width: 500,
51+
dataStructure: 'plain',
52+
parentIdExpr: 'parentKey',
53+
keyExpr: 'key',
54+
renderAsync,
55+
scrolling: {
56+
mode: 'virtual',
57+
useNaive: useNativeScrolling,
58+
},
59+
templatesRenderAsynchronously: true,
60+
columns: [{
61+
dataField: 'key',
62+
cellTemplate: 'testCellTemplate',
63+
}],
64+
integrationOptions: {
65+
templates: {
66+
testCellTemplate: {
67+
render({ model, container, onRendered }) {
68+
setTimeout(() => {
69+
container.append($('<span/>').text(model.value));
70+
onRendered();
71+
}, 100);
72+
},
73+
},
74+
},
75+
},
76+
}));
77+
});
78+
});
Loading
Loading
Loading
Loading

packages/devextreme/js/__internal/grids/grid_core/column_fixing/m_column_fixing.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ const rowsView = (Base: ModuleType<RowsView>) => class RowsViewFixedColumnsExten
10481048
super._handleScroll(e);
10491049
}
10501050

1051-
private _updateContentPosition(isRender) {
1051+
protected _updateContentPosition(isRender) {
10521052
// @ts-expect-error m_virtual_scrolling method
10531053
super._updateContentPosition.apply(this, arguments);
10541054
if (!isRender) {

packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ export class FocusController extends core.ViewController {
213213
const isAutoNavigate = that.isAutoNavigateToFocusedRow();
214214
// @ts-expect-error
215215
const d = new Deferred();
216+
const rowsView = this.getView('rowsView');
216217

217218
if (key === undefined || !this.getDataController().dataSource()) {
218219
return d.reject().promise();
@@ -239,7 +240,9 @@ export class FocusController extends core.ViewController {
239240
}).fail(d.reject);
240241
} else {
241242
this.getDataController().pageIndex(pageIndex).done(() => {
242-
that._navigateTo(key, d, needFocusRow);
243+
rowsView.waitAsyncTemplates(true).done(() => {
244+
that._navigateTo(key, d, needFocusRow);
245+
});
243246
}).fail(d.reject);
244247
}
245248
}).fail(d.reject);

packages/devextreme/js/__internal/grids/grid_core/views/m_columns_view.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ export class ColumnsView extends ColumnStateMixin(modules.View) {
10911091
const result = new Deferred();
10921092
const needWaitAsyncTemplates = forceWaiting || this.needWaitAsyncTemplates();
10931093

1094-
if (!needWaitAsyncTemplates) {
1094+
if (!needWaitAsyncTemplates || !isDefined(this._templateDeferreds)) {
10951095
return result.resolve();
10961096
}
10971097

packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1605,7 +1605,7 @@ export const rowsView = (Base: ModuleType<RowsView>) => class VirtualScrollingRo
16051605
return correctedRowHeights;
16061606
}
16071607

1608-
private _updateContentPosition(isRender?) {
1608+
protected _updateContentPosition(isRender?) {
16091609
const rowHeight = this._rowHeight || 20;
16101610

16111611
this._dataController

packages/devextreme/js/__internal/grids/tree_list/m_virtual_scrolling.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { extend } from '@js/core/utils/extend';
33
import type { DataController } from '@ts/grids/grid_core/data_controller/m_data_controller';
44
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';
55
import type { ModuleType } from '@ts/grids/grid_core/m_types';
6+
import gridCoreUtils from '@ts/grids/grid_core/m_utils';
7+
import type { RowsView } from '@ts/grids/grid_core/views/m_rows_view';
68
import {
79
data as virtualScrollingDataControllerExtender,
810
dataSourceAdapterExtender as virtualScrollingDataSourceAdapterExtender,
11+
rowsView as virtualScrollingRowsViewExtender,
912
virtualScrollingModule,
1013
} from '@ts/grids/grid_core/virtual_scrolling/m_virtual_scrolling';
1114

@@ -14,6 +17,22 @@ import gridCore from './m_core';
1417

1518
const oldDefaultOptions = virtualScrollingModule.defaultOptions;
1619

20+
virtualScrollingModule.extenders.views.rowsView = (Base: ModuleType<RowsView>) => class TreeListVirtualScrollingRowsViewExtender extends virtualScrollingRowsViewExtender(Base) {
21+
protected _handleDataChanged(e) {
22+
const { operationTypes } = e;
23+
24+
if (e?.isDataChanged && gridCoreUtils.isVirtualRowRendering(this) && operationTypes) {
25+
const { fullReload, pageIndex } = operationTypes;
26+
27+
if (!fullReload && pageIndex) {
28+
this._updateContentPosition();
29+
}
30+
}
31+
32+
super._handleDataChanged(e);
33+
}
34+
};
35+
1736
virtualScrollingModule.extenders.controllers.data = (Base: ModuleType<DataController>) => class TreeListVirtualScrollingDataControllerExtender extends virtualScrollingDataControllerExtender(Base) {
1837
protected _loadOnOptionChange() {
1938
const virtualScrollController = this._dataSource?._virtualScrollController;

0 commit comments

Comments
 (0)