Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit 91e89b3

Browse files
authored
Merge pull request #1566 from ghiscoding/bugfix/row-detail-multiple-open-close
fix: Row Detail open/close multiple times should always re-render
2 parents d812928 + c78cb9c commit 91e89b3

File tree

3 files changed

+54
-30
lines changed

3 files changed

+54
-30
lines changed

src/app/modules/angular-slickgrid/extensions/__tests__/slickRowDetailView.spec.ts

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -262,35 +262,39 @@ describe('SlickRowDetailView', () => {
262262
expect(onRowBackViewSpy).not.toHaveBeenCalled();
263263
});
264264

265-
it('should call internal event handler subscribe and expect the "onAsyncEndUpdate" option to be called when addon notify is called', () => {
266-
// const handlerSpy = vi.spyOn(plugin.eventHandler, 'subscribe');
267-
const renderSpy = vi.spyOn(plugin, 'renderViewModel');
265+
it('should call internal event handler subscribe and expect the "onAsyncEndUpdate" option to be called when addon notify is called', () =>
266+
new Promise((done: any) => {
267+
// const handlerSpy = vi.spyOn(plugin.eventHandler, 'subscribe');
268+
const renderSpy = vi.spyOn(plugin, 'renderViewModel');
268269

269-
const onAsyncRespSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAsyncResponse');
270-
const onAsyncEndSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAsyncEndUpdate');
271-
const onAfterRowSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAfterRowDetailToggle');
272-
const onBeforeRowSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onBeforeRowDetailToggle');
273-
const onRowOutViewSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onRowOutOfViewportRange');
274-
const onRowBackViewSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onRowBackToViewportRange');
270+
const onAsyncRespSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAsyncResponse');
271+
const onAsyncEndSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAsyncEndUpdate');
272+
const onAfterRowSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onAfterRowDetailToggle');
273+
const onBeforeRowSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onBeforeRowDetailToggle');
274+
const onRowOutViewSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onRowOutOfViewportRange');
275+
const onRowBackViewSpy = vi.spyOn(gridOptionsMock.rowDetailView as RowDetailView, 'onRowBackToViewportRange');
275276

276-
plugin.init(gridStub);
277-
plugin.onAsyncEndUpdate = new SlickEvent();
278-
plugin.register();
279-
plugin.onAsyncEndUpdate.notify({ item: columnsMock[0], itemDetail: columnsMock[0], grid: gridStub }, new SlickEventData(), gridStub);
277+
plugin.init(gridStub);
278+
plugin.onAsyncEndUpdate = new SlickEvent();
279+
plugin.register();
280+
plugin.onAsyncEndUpdate.notify({ item: columnsMock[0], itemDetail: columnsMock[0], grid: gridStub }, new SlickEventData(), gridStub);
280281

281-
// expect(handlerSpy).toHaveBeenCalledTimes(8); // there are an extra 2x on the grid itself
282-
// expect(handlerSpy).toHaveBeenCalledWith(
283-
// { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
284-
// expect.anything()
285-
// );
286-
expect(onAsyncRespSpy).not.toHaveBeenCalled();
287-
expect(onAsyncEndSpy).toHaveBeenCalledWith(expect.anything(), { item: columnsMock[0], itemDetail: columnsMock[0], grid: gridStub });
288-
expect(renderSpy).toHaveBeenCalledWith({ cssClass: 'red', field: 'field1', id: 'field1', width: 100 });
289-
expect(onAfterRowSpy).not.toHaveBeenCalled();
290-
expect(onBeforeRowSpy).not.toHaveBeenCalled();
291-
expect(onRowOutViewSpy).not.toHaveBeenCalled();
292-
expect(onRowBackViewSpy).not.toHaveBeenCalled();
293-
});
282+
// expect(handlerSpy).toHaveBeenCalledTimes(8); // there are an extra 2x on the grid itself
283+
// expect(handlerSpy).toHaveBeenCalledWith(
284+
// { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), },
285+
// expect.anything()
286+
// );
287+
setTimeout(() => {
288+
expect(onAsyncRespSpy).not.toHaveBeenCalled();
289+
expect(onAsyncEndSpy).toHaveBeenCalledWith(expect.anything(), { item: columnsMock[0], itemDetail: columnsMock[0], grid: gridStub });
290+
expect(renderSpy).toHaveBeenCalledWith({ cssClass: 'red', field: 'field1', id: 'field1', width: 100 });
291+
expect(onAfterRowSpy).not.toHaveBeenCalled();
292+
expect(onBeforeRowSpy).not.toHaveBeenCalled();
293+
expect(onRowOutViewSpy).not.toHaveBeenCalled();
294+
expect(onRowBackViewSpy).not.toHaveBeenCalled();
295+
done();
296+
});
297+
}));
294298

295299
it('should call internal event handler subscribe and expect the "onAfterRowDetailToggle" option to be called when addon notify is called', () => {
296300
// const handlerSpy = vi.spyOn(plugin.eventHandler, 'subscribe');

src/app/modules/angular-slickgrid/extensions/slickRowDetailView.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,14 @@ export class SlickRowDetailView extends UniversalSlickRowDetailView {
151151
this._preloadCompRef?.destroy();
152152

153153
// triggers after backend called "onAsyncResponse.notify()"
154-
this.renderViewModel(args?.item);
154+
// because of the preload destroy above, we need a small delay to make sure the DOM element is ready to render the Row Detail
155+
queueMicrotask(() => {
156+
this.renderViewModel(args?.item);
155157

156-
if (this.rowDetailViewOptions && typeof this.rowDetailViewOptions.onAsyncEndUpdate === 'function') {
157-
this.rowDetailViewOptions.onAsyncEndUpdate(e, args);
158-
}
158+
if (this.rowDetailViewOptions && typeof this.rowDetailViewOptions.onAsyncEndUpdate === 'function') {
159+
this.rowDetailViewOptions.onAsyncEndUpdate(e, args);
160+
}
161+
});
159162
});
160163

161164
this.eventHandler.subscribe(

test/cypress/e2e/example21.cy.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,21 @@ describe('Example 21 - Row Detail View', () => {
245245

246246
cy.get('#grid21').find('.slick-cell + .dynamic-cell-detail .innerDetailView_101').should('not.exist');
247247
});
248+
249+
it('should expect the Row Detail to be re-rendered after expanding/collapsing multiple times', () => {
250+
cy.get('#grid21').find('.slick-row:nth(1) .slick-cell:nth(0)').as('toggle1');
251+
cy.get('@toggle1').click();
252+
cy.get('@toggle1').click();
253+
cy.get('@toggle1').click();
254+
255+
cy.get('#grid21').find('.slick-cell + .dynamic-cell-detail .innerDetailView_1').as('detailContainer');
256+
cy.get('@detailContainer').find('h3').contains('Task 1');
257+
258+
cy.get('@toggle1').click();
259+
cy.get('@detailContainer').should('not.exist');
260+
261+
cy.get('@toggle1').click();
262+
cy.get('#grid21').find('.slick-cell + .dynamic-cell-detail .innerDetailView_1').as('detailContainer');
263+
cy.get('@detailContainer').find('h3').contains('Task 1');
264+
});
248265
});

0 commit comments

Comments
 (0)