Reputation: 73
The first time I open die ValueHelpDialog and chose an item there are no errors. However when I open the dialog again and click on the same entry I get the following error:
Uncaught Error: Error: adding element with duplicate id 'EQ5IPAKCZJMZR' at constructor.x.registerElement (Core-dbg.js:2711)...
When I click again i get another error:
Uncaught TypeError: Cannot read property 'getKey' of undefined at constructor.onVHOK (ValueHelper.js?eval:35)...
When I click a third time it works without an error.
I use
this._dialog.close();
this._dialog.destroy();
in the event handlers for the ok event as well as for the cancel event.
Is the second error related to the first one? I thought closing and destroying the dialog would be enough to avoid those duplicate id errors.
Edit: More code Controller:
this._ValueHelper = new ValueHelper();
/* Calling valueHelper */
onVH: function(oEvent) {
this._ValueHelper.handleValueHelp(this, {
srcCtrl: oEvent.getSource()
});
},
ValueHelper.js:
handleValueHelp: function(oController, mOptions) {
if (mOptions == null) {
mOptions = {};
}
this._controller = oController;
this._view = oController.getView();
this._model = this._controller.getModel();
this._callback = mOptions.fnCallback;
this._srcCtrl = mOptions.srcCtrl;
if (this._dialog != null) {
this._dialog.open();
} else {
this._buildValueHelp();
}
},
_buildValueHelp: function() {
var oDialog = sap.ui.xmlfragment(
"xxx.view.fragments.valueHelper.ValueHelp",
this
);
this._view.addDependent(oDialog);
this._dialog = oDialog;
this._registerEnterEvent(oDialog);
var oTable = sap.ui.xmlfragment(
"xxx.view.fragments.valueHelper.ValueHelpTable",
this
);
this._table = oTable;
oDialog.setTable(oTable);
oDialog.open();
},
onVHOK: function(oEvent) {
var sId = oEvent.getParameter("tokens")[0].getKey();
this._handleOk(sId);
this._dialog.close();
/*this._dialog.destroy();*/
},
onVHClose: function() {
this._dialog.close();
/*this._dialog.destroy();*/
},
ValueHelp.fragment:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:vh="sap.ui.comp.valuehelpdialog" xmlns:fb="sap.ui.comp.filterbar">
<vh:ValueHelpDialog key="id" ok="onVHOK" cancel="onVHClose" selectionChange="onVHSelectionChange"
title="Car" supportMultiselect="false" supportRanges="false" supportRangesOnly="false" descriptionKey="Car">
<vh:filterBar>
<fb:FilterBar advancedMode="true" filterBarExpanded="true" search="onVHShipSearch">
<fb:filterGroupItems>
<fb:FilterGroupItem groupName="car" name="n1" label="Name">
<fb:control>
<Input />
</fb:control>
</fb:FilterGroupItem>
<fb:FilterGroupItem groupName="car" name="n2" label="imnr">
<fb:control>
<Input/>
</fb:control>
</fb:FilterGroupItem>
</fb:filterGroupItems>
</fb:FilterBar>
</vh:filterBar>
</vh:ValueHelpDialog>
</core:FragmentDefinition>
ValueHelpTable.fragment:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:t="sap.ui.table">
<t:Table rows="{path: '/Cars'}" selectionBehavior="Row" selectionMode="Single">
<t:columns>
<t:Column>
<t:label>
<Label text="Number"/>
</t:label>
<t:template>
<Text text="{ path: 'number', formatter: '.formatter.leadingZeroes' }"/>
</t:template>
</t:Column>
<t:Column>
<t:label>
<Label text="Name"/>
</t:label>
<t:template>
<Text text="{name}"/>
</t:template>
</t:Column>
<t:Column>
<t:label>
<Label text="imnr"/>
</t:label>
<t:template>
<Text text="{imnr}"/>
</t:template>
</t:Column>
</t:columns>
</t:Table>
</core:FragmentDefinition>
Upvotes: 1
Views: 3412
Reputation: 18064
I thought closing and destroying the dialog would be enough to avoid those duplicate id errors.
Usually, it is. But the dialog is probably still being referenced by other elements. In this case, you could...:
Try to remove the references from all reference holders before destroying it.
For example, if the view has the dialog in its <dependents>
aggregation:
this._dialog.attachEventOnce("afterClose", () => {
this.getView().removeDependent(this._dialog);
this._dialog.destroy();
this._dialog = null;
}).close();
But I'm not aware of any effective ways to find all reference holders. Hence ..
Double check if it's really necessary to destroy the dialog every time after closing. Such an attempt is usually a sign of premature optimization. As long as there is no memory issue, I'd keep the dialog in memory so that it can be opened quickly next time.
If you're destroying the dialog for another reason, please add it to your question.
Upvotes: 1
Reputation: 91
I had the same problem and resolved it by making this sequence of choices.
closeIndicator: function(oEvent) {
this._dialog.close(); // First: close fragment
this._dialog.destroy(); //Second: destoy fragment
this._dialog=null; // Third: null name/pointer
},
The problem is that when you perform the destroy you do not nullify the variable.
Upvotes: 0