Skip to content

Commit 14703df

Browse files
authored
fix: registered external resouces should keep singleton ref (#262)
* fix: registered external resouces should keep singleton ref
1 parent a9b2169 commit 14703df

17 files changed

+165
-130
lines changed

package.json

+12-12
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@
9191
]
9292
},
9393
"dependencies": {
94-
"@slickgrid-universal/common": "~3.6.0",
95-
"@slickgrid-universal/custom-footer-component": "~3.6.0",
96-
"@slickgrid-universal/empty-warning-component": "~3.6.0",
97-
"@slickgrid-universal/event-pub-sub": "~3.6.0",
98-
"@slickgrid-universal/pagination-component": "~3.6.0",
94+
"@slickgrid-universal/common": "~3.7.0",
95+
"@slickgrid-universal/custom-footer-component": "~3.7.0",
96+
"@slickgrid-universal/empty-warning-component": "~3.7.0",
97+
"@slickgrid-universal/event-pub-sub": "~3.7.0",
98+
"@slickgrid-universal/pagination-component": "~3.7.0",
9999
"dequal": "^2.0.3",
100100
"dompurify": "^3.0.6",
101101
"font-awesome": "^4.7.0",
@@ -110,13 +110,13 @@
110110
"@fnando/sparkline": "^0.3.10",
111111
"@popperjs/core": "^2.11.8",
112112
"@release-it/conventional-changelog": "^8.0.1",
113-
"@slickgrid-universal/composite-editor-component": "~3.6.0",
114-
"@slickgrid-universal/custom-tooltip-plugin": "~3.6.0",
115-
"@slickgrid-universal/excel-export": "~3.6.0",
116-
"@slickgrid-universal/graphql": "~3.6.0",
117-
"@slickgrid-universal/odata": "~3.6.0",
118-
"@slickgrid-universal/rxjs-observable": "~3.6.0",
119-
"@slickgrid-universal/text-export": "~3.6.0",
113+
"@slickgrid-universal/composite-editor-component": "~3.7.0",
114+
"@slickgrid-universal/custom-tooltip-plugin": "~3.7.0",
115+
"@slickgrid-universal/excel-export": "~3.7.0",
116+
"@slickgrid-universal/graphql": "~3.7.0",
117+
"@slickgrid-universal/odata": "~3.7.0",
118+
"@slickgrid-universal/rxjs-observable": "~3.7.0",
119+
"@slickgrid-universal/text-export": "~3.7.0",
120120
"@testing-library/jest-dom": "^6.1.5",
121121
"@testing-library/react": "^14.1.2",
122122
"@testing-library/user-event": "^14.5.1",

src/examples/slickgrid/Example12.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class Example12 extends React.Component<Props, State> {
192192
sanitizeDataExport: true
193193
},
194194
excelExportOptions: { exportWithFormatter: true, sanitizeDataExport: true },
195-
registerExternalResources: [this.excelExportService, this.textExportService],
195+
externalResources: [this.excelExportService, this.textExportService],
196196
};
197197

198198
this.setState((state: State) => ({
@@ -336,4 +336,4 @@ class Example12 extends React.Component<Props, State> {
336336
}
337337
}
338338

339-
export default withTranslation()(Example12);
339+
export default withTranslation()(Example12);

src/examples/slickgrid/Example13.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ export default class Example13 extends React.Component<Props, State> {
202202
enableTextExport: true,
203203
excelExportOptions: { sanitizeDataExport: true },
204204
textExportOptions: { sanitizeDataExport: true },
205-
registerExternalResources: [this.excelExportService, this.textExportService],
205+
externalResources: [this.excelExportService, this.textExportService],
206206
};
207207

208208
this.setState((state: State) => ({

src/examples/slickgrid/Example14.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default class Example14 extends React.Component {
7070
excelExportOptions: {
7171
exportWithFormatter: false
7272
},
73-
registerExternalResources: [new ExcelExportService()],
73+
externalResources: [new ExcelExportService()],
7474
explicitInitialization: true,
7575
colspanCallback: this.renderDifferentColspan
7676
};
@@ -101,7 +101,7 @@ export default class Example14 extends React.Component {
101101
excelExportOptions: {
102102
exportWithFormatter: false
103103
},
104-
registerExternalResources: [new ExcelExportService()],
104+
externalResources: [new ExcelExportService()],
105105
gridMenu: { hideClearFrozenColumnsCommand: false },
106106
headerMenu: { hideFreezeColumnsCommand: false }
107107
};

src/examples/slickgrid/Example18.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export default class Example18 extends React.Component<Props, State> {
250250
enableExcelExport: true,
251251
excelExportOptions: { sanitizeDataExport: true },
252252
textExportOptions: { sanitizeDataExport: true },
253-
registerExternalResources: [this.excelExportService, this.textExportService],
253+
externalResources: [this.excelExportService, this.textExportService],
254254
};
255255

256256
this.setState((state: State) => ({

src/examples/slickgrid/Example23.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class Example23 extends React.Component<Props, State> {
214214
{ columnId: 'duration', direction: 'ASC' },
215215
],
216216
},
217-
registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService()],
217+
externalResources: [new SlickCustomTooltip(), new ExcelExportService()],
218218
};
219219

220220
this.setState((state: State, props: Props) => ({

src/examples/slickgrid/Example24.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ class Example24 extends React.Component<Props, State> {
304304
// you can customize how the header titles will be styled (defaults to Bold)
305305
columnHeaderStyle: { font: { bold: true, italic: true } }
306306
},
307-
registerExternalResources: [new ExcelExportService()],
307+
externalResources: [new ExcelExportService()],
308308
i18n: i18next,
309309

310310
enableContextMenu: true,

src/examples/slickgrid/Example27.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ export default class Example27 extends React.Component<Props, State> {
152152
},
153153
enableExcelExport: true,
154154
excelExportOptions: { exportWithFormatter: true, sanitizeDataExport: true },
155-
registerExternalResources: [new ExcelExportService()],
155+
externalResources: [new ExcelExportService()],
156156
};
157157

158158
this.setState((state: State) => ({

src/examples/slickgrid/Example28.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export default class Example28 extends React.Component<Props, State> {
153153
exportWithFormatter: true,
154154
sanitizeDataExport: true
155155
},
156-
registerExternalResources: [new ExcelExportService()],
156+
externalResources: [new ExcelExportService()],
157157
enableFiltering: true,
158158
enableTreeData: true, // you must enable this flag for the filtering & sorting to work as expected
159159
multiColumnSort: false, // multi-column sorting is not supported with Tree Data, so you need to disable it

src/examples/slickgrid/Example30.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ export default class Example30 extends React.Component<Props, State> {
403403
excelExportOptions: {
404404
exportWithFormatter: false
405405
},
406-
registerExternalResources: [new ExcelExportService(), this.compositeEditorInstance],
406+
externalResources: [new ExcelExportService(), this.compositeEditorInstance],
407407
enableFiltering: true,
408408
rowSelectionOptions: {
409409
// True (Single Selection), False (Multiple Selections)

src/examples/slickgrid/Example31.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export default class Example31 extends React.Component<Props, State> {
163163
this.displaySpinner(false);
164164
}
165165
} as OdataServiceApi,
166-
registerExternalResources: [new RxJsResource()]
166+
externalResources: [new RxJsResource()]
167167
};
168168

169169
this.setState((state: State) => ({
@@ -588,4 +588,4 @@ export default class Example31 extends React.Component<Props, State> {
588588
</div>
589589
);
590590
}
591-
}
591+
}

src/examples/slickgrid/Example32.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ export default class Example32 extends React.Component<Props, State> {
362362
excelExportOptions: {
363363
exportWithFormatter: false
364364
},
365-
registerExternalResources: [new ExcelExportService()],
365+
externalResources: [new ExcelExportService()],
366366
enableFiltering: true,
367367
enableRowSelection: true,
368368
enableCheckboxSelector: true,

src/examples/slickgrid/Example33.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ export default class Example32 extends React.Component<Props, State> {
331331
exportWithFormatter: true
332332
},
333333
// Custom Tooltip options can be defined in a Column or Grid Options or a mixed of both (first options found wins)
334-
registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService()],
334+
externalResources: [new SlickCustomTooltip(), new ExcelExportService()],
335335
customTooltip: {
336336
formatter: this.tooltipFormatter.bind(this) as Formatter,
337337
headerFormatter: this.headerFormatter,

src/examples/slickgrid/Example4.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ export default class Example4 extends React.Component<Props, State> {
235235
{ columnId: 'complete', direction: 'ASC' }
236236
],
237237
},
238-
registerExternalResources: [new ExcelExportService()],
238+
externalResources: [new ExcelExportService()],
239239
};
240240
}
241241

src/examples/slickgrid/Example6.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class Example6 extends React.Component<Props, State> {
315315
};
316316
});
317317
if (this.state.isWithCursor) {
318-
// When using cursor pagination, the pagination service needs to updated with the PageInfo data from the latest request
318+
// When using cursor pagination, the pagination service needs to be updated with the PageInfo data from the latest request
319319
// This might be done automatically if using a framework specific slickgrid library
320320
// Note because of this timeout, this may cause race conditions with rapid clicks!
321321
this.reactGrid?.paginationService?.setCursorPageInfo((mockedResult.data[GRAPHQL_QUERY_DATASET_NAME].pageInfo));

src/slickgrid-react/components/slickgrid-react.tsx

+53-18
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,14 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
275275
// we only want to do this check once in the constructor
276276
this._hideHeaderRowAfterPageLoad = (props.gridOptions?.showHeaderRow === false);
277277

278+
// save resource refs to register before the grid options are merged and possibly deep copied
279+
// since a deep copy of grid options would lose original resource refs but we want to keep them as singleton
280+
this._registeredResources = props.gridOptions?.externalResources || props.gridOptions?.registerExternalResources || [];
281+
/* istanbul ignore if */
282+
if (props.gridOptions?.registerExternalResources) {
283+
console.warn('[Slickgrid-Universal] Please note that the grid option `registerExternalResources` was deprecated, please use `externalResources` instead.');
284+
}
285+
278286
this._gridOptions = this.mergeGridOptions(props.gridOptions || {});
279287

280288
// initialize and assign all Service Dependencies
@@ -384,6 +392,14 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
384392
}
385393
}
386394

395+
// save resource refs to register before the grid options are merged and possibly deep copied
396+
// since a deep copy of grid options would lose original resource refs but we want to keep them as singleton
397+
this._registeredResources = this.gridOptions?.externalResources || this.gridOptions?.registerExternalResources || [];
398+
/* istanbul ignore if */
399+
if (this.gridOptions?.registerExternalResources) {
400+
console.warn('[Slickgrid-React] Please note that the grid option `registerExternalResources` was deprecated and will be removed in next major, please use `externalResources` instead.');
401+
}
402+
387403
this.initialization(this._eventHandler);
388404
this._isGridInitialized = true;
389405

@@ -622,15 +638,7 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
622638
this.serviceList = [];
623639

624640
// dispose all registered external resources
625-
if (Array.isArray(this._registeredResources)) {
626-
while (this._registeredResources.length > 0) {
627-
const resource = this._registeredResources.pop();
628-
if (resource?.dispose) {
629-
resource.dispose();
630-
}
631-
}
632-
this._registeredResources = [];
633-
}
641+
this.disposeExternalResources();
634642

635643
// dispose the Components
636644
this.slickEmptyWarning?.dispose();
@@ -678,6 +686,18 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
678686
this.componentWillUnmount(shouldEmptyDomElementContainer);
679687
}
680688

689+
disposeExternalResources() {
690+
if (Array.isArray(this._registeredResources)) {
691+
while (this._registeredResources.length > 0) {
692+
const res = this._registeredResources.pop();
693+
if (res?.dispose) {
694+
res.dispose();
695+
}
696+
}
697+
}
698+
this._registeredResources = [];
699+
}
700+
681701
componentDidUpdate(prevProps: SlickgridReactProps) {
682702
// get the grid options (order of precedence is Global Options first, then user option which could overwrite the Global options)
683703
if (this.props.gridOptions !== prevProps.gridOptions) {
@@ -1405,10 +1425,21 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
14051425
return options;
14061426
}
14071427

1428+
/** Add a register a new external resource, user could also optional dispose all previous resources before pushing any new resources to the resources array list. */
1429+
registerExternalResources(resources: ExternalResource[], disposePreviousResources = false) {
1430+
if (disposePreviousResources) {
1431+
this.disposeExternalResources();
1432+
}
1433+
resources.forEach(res => this._registeredResources.push(res));
1434+
this.initializeExternalResources(resources);
1435+
}
1436+
1437+
resetExternalResources() {
1438+
this._registeredResources = [];
1439+
}
1440+
14081441
/** Pre-Register any Resource that don't require SlickGrid to be instantiated (for example RxJS Resource) */
14091442
protected preRegisterResources() {
1410-
this._registeredResources = this.gridOptions.registerExternalResources || [];
1411-
14121443
// bind & initialize all Components/Services that were tagged as enabled
14131444
// register all services by executing their init method and providing them with the Grid object
14141445
if (Array.isArray(this._registeredResources)) {
@@ -1420,6 +1451,16 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
14201451
}
14211452
}
14221453

1454+
protected initializeExternalResources(resources: ExternalResource[]) {
1455+
if (Array.isArray(resources)) {
1456+
for (const resource of resources) {
1457+
if (this.grid && typeof resource.init === 'function') {
1458+
resource.init(this.grid, this.props.containerService);
1459+
}
1460+
}
1461+
}
1462+
}
1463+
14231464
protected registerResources() {
14241465
// at this point, we consider all the registered services as external services, anything else registered afterward aren't external
14251466
if (Array.isArray(this._registeredResources)) {
@@ -1450,13 +1491,7 @@ export class SlickgridReact extends React.Component<SlickgridReactProps, State>
14501491

14511492
// bind & initialize all Components/Services that were tagged as enabled
14521493
// register all services by executing their init method and providing them with the Grid object
1453-
if (Array.isArray(this._registeredResources)) {
1454-
for (const resource of this._registeredResources) {
1455-
if (this.grid && typeof resource.init === 'function') {
1456-
resource.init(this.grid, this.props.containerService);
1457-
}
1458-
}
1459-
}
1494+
this.initializeExternalResources(this._registeredResources);
14601495
}
14611496

14621497
/** Register the RxJS Resource in all necessary services which uses */

0 commit comments

Comments
 (0)