在我的应用程序中,我必须渲染项目,任务和里程碑。项目和任务是不同颜色的条形,里程碑是钻石(我分别使用BaseRectangle
和BaseDiamond
)。
由于我的层次结构中的某些项目是“项目”,“某些任务”和“某些里程碑”,因此如何在每行上呈现不同的形状?
我的第一个想法是使用常见的“可见”属性,但形状没有那个,相反“不透明”使事物不可见,但它们仍然响应鼠标位置。
然后我尝试使用聚合工厂函数,但是虽然我的图表在第一次显示时正确呈现,但它不会重新计算展开或折叠分支上的形状。
在我看来,工厂函数应该工作,但在图表中的一些东西正在打破,不会给控制台抛出错误。
目前在我的XML模板中,我有以下内容:
rowSettingTemplate
有shapes1={path: factory:}
,没有shapes1
元素。BaseShapes
都是一个不同的片段,作为家属附在我的TreeTable
上。示例形状片段 - Project.fragment.xml
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:gnt2="sap.gantt.simple">
<gnt2:BaseRectangle id="shapeProject"
shapeId="{plandata>id}" countInBirdEye="true"
time="{plandata>start_date}" endTime="{plandata>end_date}"
resizable="true" selectable="true" draggable= "true" connectable="true"
title="{plandata>text}" showTitle="true"
tooltip=""
fill="#0c1" />
</core:FragmentDefinition>
工厂功能:
shapeFactory: function(sId, oContext) {
var parentId = (/(.*)-\d+$/.exec(sId))[1];
var rowSettings = sap.ui.getCore().byId(parentId);
var node: Project.Node = oContext.getProperty();
if (String(node.id) == rowSettings.getProperty("rowId")) {
switch (node.type) {
case "project":
return this.byId('shapeProject').clone(sId);
case "task":
return this.byId('shapeTask').clone(sId);
case "milestone":
return this.byId('shapeMilestone').clone(sId);
default:
return this.byId('shapeErr').clone(sId);
}
} else {
return this.byId('shapeEmpty').clone(sId);
}
}
我的空形是一个BaseGroup
- 请注意,如果我从工厂返回一个null
,SAPUI5会崩溃,所以当我什么都不想要的时候必须返回一些东西。
我还尝试在BaseGroup
中包装我的所有形状,以便图表始终看到相同的控件类型,但这不起作用。另请注意,如果我每次都返回Empty
的克隆而没有任何特殊逻辑,那么图表可以正常工作。
我希望这是一个设置或某些东西,以确保聚合每次都正常工作。我的SAPUI5版本是1.61.2 - 当我有时间时我会尝试1.63.1,但我认为这个问题相当深刻。
如果有人有任何想法或示例代码,将不胜感激。
我想出了一个解决方法,这可能会节省几个小时。基本上不是通过工厂函数定义shapes1聚合,而是使用了<shapes1>
标签。 My Shapes1标签包含对我自己的自定义形状的引用,该形状派生自BaseRectangle。然后,我的自定义形状可以根据绑定的对象上下文呈现它需要的任何SVG。现在,我的树可以展开和折叠,同时渲染所需的任何形状。
我的渲染器现在看起来像这样:
CustomChartShape.prototype.renderElementRectangle = BaseRectangle.prototype.renderElement;
CustomChartShape.prototype.renderElementDiamond = BaseDiamond.prototype.renderElement;
CustomChartShape.prototype.renderElement = function(oRm, oElement) {
// There is possibilities that x is invalid number.
// for instance wrong timestamp binded to time property
if (this.bHasInvalidPropValue) { return; }
var Node = this.getBindingInfo('endTime').binding.getContext().getProperty();
if (Node.type == "milestone") {
this.renderElementDiamond(oRm, oElement);
} else {
this.renderElementRectangle(oRm, oElement);
}
}
我必须提供一个具有固定宽度的'getD'函数,我将通过并重写几个函数,但我认为这对我有用。