Looks like we have a bug in our Element garbage detection method (it doesn't account for the fact that the element in question might be replacing a recently removed element with the same ID)
1. Is this considered 'wrongful' use of your Grid / Element API?
2. Can we somehow opt out of the caching, or it's checks?
3. This was fine in Ext 4.x, is there an override to get back the old way?
1) Yes, I believe so. Because the elements you're referring to are transient, you can never really hold a reference to them so each time you need an access you have to call get(), then you should really be using fly().
2) Use fly() to not cache, but otherwise there's no way to opt-out of caching
3) Phil's got an override
So in short, it's a bug, I'd say it's not good practice to be doing it in they way you've got it now.
Twitter - @evantrimboli
Former Sencha framework engineer, available for consulting.
As of 2017-09-22 I am not employed by Sencha, all subsequent posts are my own and do not represent Sencha in any way.
@mankz @Zdeno Will be fixed in next release - here's a workaround for now:
Code:
Ext.require('Ext.dom.Element', function() {
Ext.isGarbage = function(dom) {
// determines if the dom element is in the document or in the detached body element
// use by collectGarbage and Ext.get()
return dom &&
// Must be an element. window, document and documentElement can never be garbage.
dom.nodeType === 1 &&
// if the element does not have a parent node, it is definitely not in the
// DOM - we can exit immediately
(!dom.parentNode ||
// If the element has an offset parent we can bail right away, it is
// definitely in the DOM.
(!dom.offsetParent &&
// if the element does not have an offsetParent it can mean the element is
// either not in the dom or it is hidden. The next step is to check to see
// if it can be found by id using either document.all or getElementById(),
// whichever is faster for the current browser. Normally we would not
// include IE-specific checks in the sencha-core package, however, in this
// case the function will be inlined and therefore cannot be overridden in
// the ext package.
((Ext.isIE8 ? document.all[dom.id] : document.getElementById(dom.id)) !== dom) &&
// finally if the element was not found in the dom by id, we need to check
// the detachedBody element
!(Ext.detachedBodyEl && Ext.detachedBodyEl.isAncestor(dom))));
};
});
Still probably best to avoid using Ext.get() for this type of thing anyway. Use Ext.fly() for quick and easy access to the Ext.Element api (unless you need to attach listeners). Ext.fly() will bypass the caching mechanism
I have placed your code into Application.js (I'm not sure if this is the right place).
But error is still there (tested on IE11):
"
DOM element with id ext-gen2 in Element cache is not the same as element in the DOM. Make sure to clean up Element instances using destroy()
"
I have included my example as attachment - index.html. You just have to replace library path.
I saw this issue today in ext 5.1 in IE8. I have a card layout that includes a box. I am updating the box html based on events in the app. I am using a callback on the update() method (and resize listener) to get elements on the html to size them like so.
var node = this.el.getById('myId');
node.setHeight(value);
I got around this using Ext.fly() instead, but it appears there is still a garbage collection issue since the node with myId is replaced by the call to update().
We also have this problem. We included the calendar example in our project and started customizing it. Sometimes, mostly when trying to drag and drop an event in the week view this error will appear and disappear at random. I'm reluctant on using Ext.fly since i'm not 100% familiar with the calendar's code yet and I'm not sure it can replace Ext.get(). I'll try to find an exact scenario where this error appears and post again.