PDA

View Full Version : Ext.AbstractManager.register(): Registering duplicate id "[component_name]"...



Jangla
26 Feb 2013, 11:45 PM
For reasons I won't go into, I'm having to use a component with a loader to render out some markup into a form in a tabpanel and then on the callback for the loader, add some checkboxes to the markup.

Only trouble is, while this worked fine in Ext3, in Ext4 it would seem that closing the window isn't destroying the checkboxes in the Abstract Manager correctly as this error is being generated if you re-open the window:

Ext.AbstractManager.register(): Registering duplicate id "displaycontainer-2" with this manager

The window is set to destroy on close. So, is there anyway I can correct this? I've tried something like the following in the render listener of each of the checkboxes but you can't retrieve the reference to the window successfully from there:




var window = this.findParentByType( 'window' )


window.on('destroy', function() {
this.destroy();
}, this)

evant
26 Feb 2013, 11:55 PM
So the code that you're running "for reasons you won't go into", what does it look like?

Jangla
27 Feb 2013, 1:06 AM
...
{
xtype : 'component',
id : 'myComponent',
height : '100%',
loader : {
url : '/path/to/some/markup',
scripts : true,
params : {
id : myId
},
autoLoad : true,
callback : function() {
Ext.each(Ext.query('.checkbox-container'), function(item, idx, items) {
var itemId = item.getAttribute('data-itemId')
Ext.create('Ext.Container', {
renderTo: 'channelbox-check-' + itemId,
items : {
id : 'channelbox-' + itemId,
xtype : 'checkbox',
inputValue: itemId,
checked : false,
name : 'channelContainers',
hideLabel : true,
boxLabel : item.getAttribute('data-boxLabel'),
labelStyle: 'width : 100%; float : none',
listeners : {
render : function() {


var window = this.findParentByType( 'window' ), form = window.down( 'ngxformpanel' );


window.on('destroy', function() {
this.destroy();
}, this)


}
}
}
})
})
}
}
}
...



So this loader will grab some basic markup and then iterate over elements in it, adding in checkboxes where required. The render listener is my most recent attempt to get rid of the AbstractManager error and wasn't present in the Ext3 version of our code.

evant
27 Feb 2013, 2:10 AM
So does this mean you're creating containers and calling renderTo into some element that's a child of the window?

Jangla
27 Feb 2013, 2:24 AM
So does this mean you're creating containers and calling renderTo into some element that's a child of the window?

Yea.

Window -> TabPanel -> Component that loads markup including container divs

loader callback renders checkboxes to container divs

Closing window and reopening causes error. I'm therefore assuming that the checkboxes rendered into those container divs are not removed from the AbstractManager when the window is destroyed.

Also, this:




var window = this.findParentByType( 'window' )



...doesn't return the window as I would expect so I'm guessing the checkbox has no idea what it's parent containers are.

evant
27 Feb 2013, 3:00 AM
You should absolutely not be doing that. By calling renderTo, the container has no idea those child components exist, which means when you destroy the window, the markup goes away, but none of the component references do. You should use the standard container methods.

This is in the docs:



Do not use this option if the Component is to be a child item of a Container. It is the responsibility of the Container's layout manager to render and manage its child items.

Jangla
1 Mar 2013, 3:27 PM
Sorry if this is a dumb question, but are you saying that the entire process I'm attempting is impossible (container calling a url to load markup and then attaching elements to that markup) or that I just need to use different calls rather than renderTo?

evant
1 Mar 2013, 7:34 PM
It's certainly possible, just the approach you're using is prone to memory leaks (and other problems) because components have their DOM overwritten but nothing ever gets cleaned up. You need to use the container API (add/remove etc) to manage children.

Jangla
2 Mar 2013, 11:58 AM
Yea, I don't think it's going to be possible though.

Imagine the markup the container is loading is something like this:



<div class='outerWrapper'>
<div class='innerWrapper'>
<div class='checkContainer'></div>
<div class='checkContainer'></div>
<div class='checkContainer'></div>
</div>
</div>

<div class='outerWrapper'>
<div class='innerWrapper'>
<div class='checkContainer'></div>
</div>
</div>


I don't see how add will work - it won't allow me to add checkboxes at the required points in the markup itself, it will just add them to the bottom of the container, no?

evant
2 Mar 2013, 2:05 PM
You could, assuming you wrapped them in components appropriately, without knowing your use case I can't really say.

The only 2 options are:

1) Use the container API
2) Ensure you keep track of and manually clean up anything that you've used a renderTo on (much less preferred)