sapui5/openui5 TreeTable с пользовательским столбцом управления, выдающим ошибку дублирующегося идентификатора при расширении узла
У меня есть sap.ui.table.TreeTable
с несколькими столбцами, один из которых содержит пользовательский элемент управления, определенный как шаблон для столбца.
TreeTable отображается правильно, а столбец с пользовательским элементом управления также отображается и работает правильно... до тех пор, пока я не разверну нерасширенный узел.
Когда я раскрываю узел, рендерер выдает ошибку Error: adding element with duplicate id '__link0-col1-row0'
,
который является столбцом, связанным с пользовательским элементом управления.
Я могу обойти эту проблему, добавив обработчик события attachToggleOpenState, который уничтожает этот шаблон столбцов и добавляет его снова. Дорого, но это работает!
this.oTable = new sap.ui.table.TreeTable("myTable", {
columns : [ new sap.ui.table.Column( {
label : "Query",
template : new sparqlish.control.queryClause({
clausePath : {
path : "viewModel>path"
}
}),
visible : true,
width : "500px"
}), ],
}).attachToggleOpenState(function(oEvent) {
// TODO workaround as expanding Tree causes duplicate id
var queryColumn = oEvent.getSource().getColumns()[0];
queryColumn.destroyTemplate();
queryColumn.setTemplate(new sparqlish.control.queryClause({
clausePath : {
path : "viewModel>path"
}
}))
});
sparqlish.control.queryClause - это пользовательский элемент управления.
Я использую openui5 версии 1.28.15
Любые другие, менее дорогие, предложения?
Пользовательский элемент управления принимает эту форму, однако этот элемент управления вызывает другие элементы управления и так далее.
jQuery.sap.require("sparqlish.control.conceptClause");
jQuery.sap.require("sparqlish.control.propertyClause");
jQuery.sap.require("sparqlish.control.conjunctionPropertyClause");
sap.ui.core.Control.extend("sparqlish.control.queryClause", {
metadata : {
properties : {
clausePath : {
type : "string"
}
},
events : {},
aggregations : {
_conceptClause : {
type : "sparqlish.control.conceptClause",
multiple : false
},
_propertyClause : {
type : "sparqlish.control.propertyClause",
multiple : false
},
_conjunctionPropertyClause : {
type : "sparqlish.control.conjunctionPropertyClause",
multiple : false
}
}
},
init : function() {
var self = this;
self.setAggregation("_conceptClause", new sparqlish.control.conceptClause());
self.setAggregation("_propertyClause", new sparqlish.control.propertyClause());
self.setAggregation("_conjunctionPropertyClause", new sparqlish.control.conjunctionPropertyClause());
},
renderer : function(oRm, oControl) {
if (oControl.getClausePath() != undefined) {
// TODO no point if path not yet defined
oRm.write("<div ");
oRm.writeControlData(oControl);
oRm.writeClasses();
oRm.write(">");
var currentModel = oControl.getModel("queryModel");
// Set binding context, rather than just the binding path etc, as this seems essential for satisfactory binding of
// aggregations
oControl.setBindingContext(new sap.ui.model.Context(oQueryModel, oControl.getClausePath()), "queryModel")
var currentCtx = oControl.getBindingContext("queryModel");
var currentContext = oControl.getModel("queryModel").getProperty("", currentCtx);
if (currentContext != undefined) {
var sClass = currentContext._class;
if (sClass == "Query") {
oControl.setAggregation("_conceptClause", new sparqlish.control.conceptClause().setBindingContext(oControl.getBindingContext("queryModel")));
oRm.renderControl(oControl.getAggregation("_conceptClause"));
} else if (sClass == "Clause") {
oControl.setAggregation("_propertyClause", new sparqlish.control.propertyClause().setBindingContext(oControl.getBindingContext("queryModel")));
oRm.renderControl(oControl.getAggregation("_propertyClause"));
} else if (sClass == "ConjunctionClause") {
oControl.setAggregation("_conjunctionPropertyClause", new sparqlish.control.conjunctionPropertyClause().setBindingContext(oControl
.getBindingContext("queryModel")));
oRm.renderControl(oControl.getAggregation("_conjunctionPropertyClause"));
} else {
jQuery.sap.log.fatal("Incorrect class of provided query clause");
}
}
oRm.write("</div>");
} else {
jQuery.sap.log.fatal("clausePath not defined");
}
}
});
Пример одного из зависимых элементов управления приведен ниже.
jQuery.sap.require("sparqlish.control.conceptMenu");
jQuery.sap.require("sparqlish.control.conceptFilters");
jQuery.sap.require("sparqlish.control.addClause");
sap.ui.core.Control.extend("sparqlish.control.conceptClause", {
metadata : {
properties : {
concept : "object"
},
events : {},
aggregations : {
_concept : {
type : "sparqlish.control.conceptMenu",
multiple : false
},
_conceptFilters : {
type : "sparqlish.control.conceptFilters",
multiple : false
},
_addClause : {
type : "sparqlish.control.addClause",
multiple : false
}
}
},
init : function() {
var self = this;
var conceptSelect =function(oEvent){
var currentModel = self.getModel("queryModel");
var currentContext = self.getBindingContext("queryModel");
var currentModelData = currentModel.getProperty("", currentContext);
currentModelData.conceptFilters = [];
currentModelData.clauses = {};
var sConcept = oEvent.getParameter("concept");
var oMetaModel = self.getModel("metaModel");
var oConcept=oMetaModel.getODataEntitySet(sConcept);
self.setConcept( oConcept);
self.oEntityTypeModel = new sap.ui.model.json.JSONModel();
self.oEntityTypeModel.setData(oMetaModel.getODataEntityType(oConcept.entityType));
self.setModel(self.oEntityTypeModel, "entityTypeModel");
self.getAggregation("_conceptFilters").setModel(self.oEntityTypeModel, "entityTypeModel");
self.getAggregation("_conceptFilters").getAggregation("_extendFilter").setVisible(true);
currentModel.refresh();
self.rerender();
};
self.setAggregation("_concept", new sparqlish.control.conceptMenu({
selected : function(oEvent) {
self.getAggregation("_conceptFilters").getAggregation("_extendFilter").setVisible(true);
},
changed : conceptSelect
}).bindElement("queryModel>"));
self.setAggregation("_conceptFilters", new sparqlish.control.conceptFilters().bindElement("queryModel>"));
self.setAggregation("_addClause", new sparqlish.control.addClause({
pressed : function(oEvent) {
alert("concept");
}
}).bindElement("queryModel>"));
},
renderer : function(oRm, oControl) {
oRm.addClass("conceptClause");
oRm.write("<div ");
oRm.writeControlData(oControl);
oRm.writeClasses();
oRm.write(">");
oRm.write(sap.ui.getCore().getModel("i18nModel").getProperty("conceptClauseFind"));
oRm.renderControl(oControl.getAggregation("_concept"));
oRm.renderControl(oControl.getAggregation("_conceptFilters"));
oRm.write(" ");
oRm.renderControl(oControl.getAggregation("_addClause"));
oRm.write("</div>");
}
});