No way of temporarily displaying a grid and removing it, as clean up isn't implemented
Hi,
Thanks for a great library! :-) I've created some proof-of-concepts at work using the older version.
Right now I'm looking to open a "widget" (terrible name I know) that contains a grid. The user can close the widget. Therefore, it needs to have its resources cleaned up.
grid.stopPaintThread() and grid.stopResizeThread() are not hooked up correctly and throw.
I can call grid.canvas.stopPaintLoop() successfully to stop hooking into requestAnimationFrame instead.
However, there is currently no way to remove the document level events that the canvas hooks up. This causes exceptions to be thrown once the element containing the div is removed from the page.
See: https://github.com/fin-hypergrid/core/blob/master/src/lib/Canvas.js#L53
@ZachBray This is a good point. Are you interested in offereing a PR?
It appears the anonymous functions in the document events cannot be removed, so creating handlers and a remove function works.
I was able to make a workaround with the following:
//Comment out the document.addEventListeners
function Canvas(div, component) {
...
//document.addEventListener('mousemove', function(e) {
// if (self.hasMouse || self.isDragging()) {
// self.finmousemove(e);
// }
//});
//document.addEventListener('mouseup', function(e) {
// self.finmouseup(e);
//});
//document.addEventListener('wheel', function(e) {
// self.finwheelmoved(e);
//});
//document.addEventListener('keydown', function(e) {
// self.finkeydown(e);
//});
//document.addEventListener('keyup', function(e) {
// self.finkeyup(e);
//});
//Add these in place of the commented out lines
this.handlerDocumentEventMouseMove = function (e) {
if (self.hasMouse || self.isDragging()) {
self.finmousemove(e);
}
};
this.handlerDocumentEventMouseUp = function (e) {
self.finmouseup(e);
};
this.handlerDocumentEventWheel = function (e) {
self.finwheelmoved(e);
};
this.handlerDocumentEventKeyDown = function (e) {
self.finkeydown(e);
};
this.handlerDocumentEventKeyUp = function (e) {
self.finkeyup(e);
};
//add the listeners
document.addEventListener('mousemove', this.handlerDocumentEventMouseMove);
document.addEventListener('mouseup', this.handlerDocumentEventMouseUp);
document.addEventListener('wheel', this.handlerDocumentEventWheel);
document.addEventListener('keydown', this.handlerDocumentEventKeyDown);
document.addEventListener('keyup', this.handlerDocumentEventKeyUp);
//function to remove the listeners
this.documentRemoveEventListeners = function () {
document.removeEventListener('mousemove', this.handlerDocumentEventMouseMove);
document.removeEventListener('mouseup', this.handlerDocumentEventMouseUp);
document.removeEventListener('wheel', this.handlerDocumentEventWheel);
document.removeEventListener('keydown', this.handlerDocumentEventKeyDown);
document.removeEventListener('keyup', this.handlerDocumentEventKeyUp);
};
</code
Then to remove the grid in your page
var el = document.getElementById("mydiv");
// removes canvas event listeners
gridVar.reset();
// removes document event listener mousedown
gridVar.terminate();
// removes document event listeners to canvas (mouseup, mousedown, wheel, keydown, keyup)
gridVar.canvas.documentRemoveEventListeners();
//remove the canvas and other elements
while (el.hasChildNodes()) {
el.removeChild(el.lastChild);
}
// clean up the variable
gridVar = null;
If your grid variable is inside a class, you may need put the "new fin.Hypergrid(...)" inside a prototype function instead of the constructor, or the document events might not be removed.
It can be verified by counting the events with the console command: getEventListeners(document)
@joneit Are you able to take a look at this?
This prevents everyone from using this in applications that are based on a component approach. Having a defined lifecycle and cleaning up after yourself is vital in those scenarios.
Every hypergrid subclass that manipulates dom or events etc and allocates resources should have it's own "terminate" Method and all of them should be called by the grids "terminate" in my opinion.
Seeing that this is unfixed for years, how can one monkey patch the Canvas-constructor from the outside? The approach by @willsolve seems correct (maybe needs to be adjusted for the current version).
Not a big fan of editing around in the local source files, would like to take an "override" based approach to this if possible?