diff --git a/addon/components/grid-stack.js b/addon/components/grid-stack.js index 46e8d2f..7d81353 100644 --- a/addon/components/grid-stack.js +++ b/addon/components/grid-stack.js @@ -159,7 +159,7 @@ export default class GridStackComponent extends Component { el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM } }); - if (triggerEvent) { + if (triggerEvent && !this.isDestroying && !this.isDestroyed) { this.gridStack?._triggerRemoveEvent(); this.gridStack?._triggerChangeEvent(); } diff --git a/tests/integration/components/grid-stack-test.js b/tests/integration/components/grid-stack-test.js index 1d9b5b7..0565de8 100644 --- a/tests/integration/components/grid-stack-test.js +++ b/tests/integration/components/grid-stack-test.js @@ -145,8 +145,7 @@ module('Integration | Component | grid stack', function (hooks) { }); test('onChange, onAdded, onRemove actions', async function (assert) { - // onAdded should run twice, onChange once, onRemoved twice - assert.expect(15); + assert.expect(12); this.set('items', A([1])); @@ -303,4 +302,37 @@ module('Integration | Component | grid stack', function (hooks) { .dom(`[data-id="3"]`) .hasAttribute('gs-y', '2', 'Updating a grid-stack-item moves conflicting items to a different row'); }); + + test('do not fire `onChange` or `onRemoved` during teardown', async function (assert) { + assert.expect(1); + + this.set('shouldRender', true); + this.set('items', [ + { id: 0, options: { x: 0, y: 0, w: 5, h: 1 } }, + { id: 1, options: { x: 6, y: 0, w: 3, h: 1 } }, + { id: 2, options: { x: 0, y: 1, w: 4, h: 1 } }, + { id: 3, options: { x: 6, y: 1, w: 2, h: 1 } }, + ]); + + this.onChange = () => assert.notOk(true, '`onChange` should not fire on teardown'); + this.onRemoved = () => assert.notOk(true, '`onRemoved` should not fire on teardown'); + + await render(hbs` + {{#if this.shouldRender}} + + {{#each this.items as |item|}} + + {{item.id}} + + {{/each}} + + {{/if}} + `); + + this.set('shouldRender', false); + assert.ok(true, 'all is good'); + }); });