GridCore data: Merge DataHelperMixin into DataController - #34938
Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes the grid_core-specific DataHelperMixin and folds its remaining data-source lifecycle responsibilities into grid_core’s DataController, reducing reliance on generic mixin plumbing and making DataController the single place that wires data-source readiness/disposal behavior.
Changes:
- Removed
DataHelperMixinand stopped extending it fromDataController. - Inlined data-source lifecycle hooks into
DataController(init/refresh + ready-watcher wiring) and introduced_createRawDataSource()to construct the rawDataSourcebefore adapter wrapping. - Updated search code to read
langParamsviagetDataSource()directly.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/devextreme/js/__internal/grids/grid_core/search/m_search.ts | Adjusts how langParams is retrieved (via getDataSource()), aligning with the removal of the mixin-held controller path. |
| packages/devextreme/js/__internal/grids/grid_core/data_controller/data_helper_mixin.ts | Removes the mixin implementation entirely. |
| packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts | Integrates the mixin’s data-source lifecycle setup into DataController and adds _createRawDataSource() + ready-watcher wiring. |
Suppressed comments (1)
packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts:716
_createRawDataSource()disposes the previous adapter but doesn’t unsubscribereadyWatcherfrom the previous raw DataSource, and it never clears_isSharedDataSourceafter disposal. If the previous dataSource was shared and the new one is not, the stale_isSharedDataSourceflag can cause future adapters to be disposed as “shared” (skipping dispose) and theloadingChangedsubscription can leak. Detach the listener before disposing and reset_isSharedDataSourceafter disposal.
private _createRawDataSource(): DataSource | undefined {
const dataSourceOptions = this._getSpecificDataSourceOption();
this._disposeDataSource();
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| protected readyWatcher?: (isLoading: boolean) => void; | ||
|
|
||
| protected _ready?: (value?: boolean) => void; |
There was a problem hiding this comment.
Looks like the 'ready' callback is never set and used. If that's true, let's remove readyWatcher and _ready
| const isSharedDataSource = dataSourceOptions instanceof DataSourceClass; | ||
|
|
||
| this._isSharedDataSource = isSharedDataSource; |
There was a problem hiding this comment.
optional code-style suggestion, use just this._isSharedDataSource prop and delete var:
this._isSharedDataSource = dataSourceOptions instanceof DataSourceClass;| public postInit(): void { | ||
| this.on('disposing', () => { | ||
| this._disposeDataSource(); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Do we really need postInit() method? I see that dataController.dispose() already calls _disposeDataSource()
| /** | ||
| * @extended: state_storing, virtual_scrolling | ||
| */ | ||
| protected _refreshDataSource(): DeferredObj<unknown> | undefined { |
There was a problem hiding this comment.
What do you think about renaming the method to resetDataSource()?
I think that name expresses what this function does more clearly than the current name
There was a problem hiding this comment.
i don't object about it
|
|
||
| protected _calculateAdditionalFilter(): DataFilter { | ||
| const dataSource = this._dataController?.getDataSource?.(); | ||
| const dataSource = this.getDataSource?.(); |
…ename to resetDataSource
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts:708
- When the dataSource option is cleared (null/undefined/0/''),
_createRawDataSourcereturns early without updating_isSharedDataSource, so the flag can retain the previous value even though there is no current data source. This makes_isSharedDataSourcereflect stale state and can lead to confusing behavior for any code/tests that reads it after clearing the dataSource.
if (!dataSourceOptions) {
return undefined;
}
| } | ||
| } | ||
|
|
||
| private _createRawDataSource(): DataSource | undefined { |
There was a problem hiding this comment.
lets remove _ for added fields and methods (except _dataSource may be - if it assumes multiple changes through code base)
| const dataSource = (isSharedDataSource | ||
| ? dataSourceOptions | ||
| : new DataSourceClass( | ||
| extend(true, {}, normalizeDataSourceOptions(dataSourceOptions, { fromUrlLoadMode: false })), |
There was a problem hiding this comment.
a bit difficult to read, after readyWatcher removed, then lets use early return
- { fromUrlLoadMode: false } is excessive, empty options object can be passed
| extend(true, {}, normalizeDataSourceOptions(dataSourceOptions, { fromUrlLoadMode: false })), | |
| extend(true, {}, normalizeDataSourceOptions(dataSourceOptions, {})), |
| } | ||
| } | ||
|
|
||
| private _createRawDataSource(): DataSource | undefined { |
There was a problem hiding this comment.
incorrect naming - this method not only creates new raw data source, but also disposes existing one
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
packages/devextreme/js/__internal/grids/grid_core/data_controller/tests/data_controller.data_source.test.ts:55
- After changing the dataSource option, the controller update/load cycle is async in these tests. Add
await flushAsync()before asserting on internal controller state to avoid flaky timing-dependent failures.
instance.option('dataSource', DATA);
expect(getIsSharedDataSource(instance)).toBe(false);
…re on isSharedDataSource, reset flag on every path
…atacontroller-merge-datahelper-mixin-26_2
What
Removes the grid_core-only
DataHelperMixinand folds its data-source lifecycle logic directly into DataController, so the controller no longer carries unused generic mixin machinery. Also fixes a pre-existing case where the shared-data-source flag stayed set after switching to a non-shared sourceHow
Inlined the live parts (
postInit,_refreshDataSource, ready-watcher wiring) into data_controller.ts and dropped the dead generic paths that grid_core never exercised. The rawDataSourceis now built by a local_createRawDataSourcehelper so_dataSourceonly ever holds the adapter, and_isSharedDataSourceis now assigned on every path