我的目标是创建一个面板,我可以拖放两种不同类型的元素:按钮和文本字段。所有元素都存储在TreeMap中,并使用JSTL <c:forEach>
标记进行迭代。我可以添加额外的组件,并通过viewPanel外部的专用p:commandXxx字段删除最近选择的组件。一旦可拖动的组件在viewPanel中,我就可以拖放它们。通过javascript,我会在调用放置操作之前附加特定组件的顶部和左侧坐标以更新组件的位置。 delete commandButton应该从列表中删除所选元素并触发viewPanel的更新。
问题:删除除最近添加的组件之外的任何组件都无法更新viewPanel,从而导致以下异常:
严重:错误渲染视图[/developer/testDr.xhtml] org.primefaces.expression.ComponentNotFoundException:无法找到&gt;表达式组件&#34;按钮 - &#34;引自&#34; defStep-10:j_idt13&#34;。。
似乎在渲染时间中,可拖动的 for 属性将#{child.idstepNode}评估为null。有谁知道为什么会这样,或者如何绕过这个?
有趣的是,当再次单击“删除”按钮或刷新整个页面时,viewPanel会毫不费力地呈现。
<h:form id="viewPanel" class="default-step droppable" style="width:500px;height:500px;background:green;">
<p:droppable for="viewPanel" tolerance="touch" activeStyleClass="ui-state-highlight" >
<p:ajax listener="#{stepUtility.onDrop}" update="viewPanel" />
</p:droppable>
<c:forEach items="${stepUtility.stepNodesMap}" var="child">
<c:if test="${child.value.elementType == 'BUTTON'}">
<p:outputLabel id="button-${child.value.idstepNode}" style="top:${child.value.top};left:${child.value.left};
background-color: beige;position:absolute;" value="button ${child.value.elementValue}"/>
<p:draggable for="button-${child.value.idstepNode}"/>
</c:if>
<c:if test="${child.value.elementType == 'TEXT'}">
<p:outputLabel id="text-${child.value.idstepNode}" style="top:${child.value.top};left:${child.value.left};
background-color: beige;position:absolute;" value="text ${child.value.elementValue}"/>
<p:draggable for="text-${child.value.idstepNode}" />
</c:if>
</c:forEach>
</h:form>
//...
<p:commandButton value="Delete" actionListener="#{stepUtility.removeStepNode()}"
update=":viewPanel"/>
stepUtility bean
@Named(value = "stepUtility")
@SessionScoped
public class StepUtility implements Serializable {
private Integer selecteNode;
public void setSelectedElement(Integer idstepNode) //'StepNode')
{
selecteNode=idstepNode;
}
public void addNewComp(String typeNode)
{
if(stepNodesMap == null)
stepNodesMap = new TreeMap<>();
StepNodeSimple snode = new StepNodeSimple();
Integer id = 0;
if(stepNodesMap.size()>0)
{
Integer lastNodeId = ((StepNodeSimple) stepNodesMap.lastEntry().getValue()).idstepNode;
id = lastNodeId+1;
}
snode.idstepNode = id;
snode.elementType = typeNode;
snode.elementValue = typeNode +"value";
snode.left = "2px;";
snode.top = "2px;";
stepNodesMap.put(id, snode);
}
NavigableMap stepNodesMap;
public NavigableMap getStepNodesMap() {
return stepNodesMap;
}
public void setStepNodesMap(NavigableMap stepNodesMap) {
this.stepNodesMap = stepNodesMap;
}
public void removeStepNode()
{
if(selecteNode!=null)
{
stepNodesMap.remove(selecteNode);
}
}
public void onDrop(DragDropEvent dragDropEvent)
{
String dragId = dragDropEvent.getDragId();
Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String left = params.get(dragId + "_left");
String top = params.get(dragId + "_top");
Integer idstepNode = Integer.parseInt(dragId.substring(dragId.lastIndexOf("-")+1));
setSelectedElement(idstepNode);
StepNodeSimple element = (StepNodeSimple) stepNodesMap.get(selecteNode);
element.left = left+"px;";
element.top = top+"px;";
}
}