如何以编程方式更新Tree ContextMenu?
我已经像这样定义了菜单:
<p:contextMenu id="treeMenu" widgetVar="treeMenuWidget" for="treeSingle" model="#{treeBean.model}"/>
然后在bean中,getModel定义如下:
public MenuModel getModel() {
model = new DefaultMenuModel();
log.debug("node=<" + node + ">");
if (node != null){
NodeInfo info = node.getNodeInfo();
log.debug("info=<" + info + ">");
if (info != null){
if (info.isWritable()){
if (info.isLeaf()){
MenuItem item = new MenuItem();
item.setValue("Edit");
item.setIcon("ui-icon-pencil");
item.addActionListener(FacesUtil.createMethodActionListener("#{treeBean.edit}",
Void.class,
new Class[] {ActionEvent.class}));
model.addMenuItem(item);
}else{
MenuItem item = new MenuItem();
item.setValue("View");
item.setIcon("ui-icon-search");
item.addActionListener(FacesUtil.createMethodActionListener("#{treeBean.view}",
Void.class,
new Class[] {ActionEvent.class}));
model.addMenuItem(item);
}
}else{
MenuItem item = new MenuItem();
item.setValue("View Read Only");
item.setIcon("ui-icon-search");
item.addActionListener(FacesUtil.createMethodActionListener("#{treeBean.viewAll}",
Void.class,
new Class[] {ActionEvent.class}));
model.addMenuItem(item);
}
}
}
return model;
}
当我像这样定义树时,onNodeSelect()和getModel()函数永远不会被调用来更新当前树节点或contextmenu:
<p:tree id="treeSingle"
value="#{treeBean.root}"
var="node"
selectionMode="single"
selection="#{treeBean.selectedNode}"
dynamic="false"
cache="false"
style="width:100%;height:100%;">
<p:treeNode>
<c:if test="#{!empty node.icon}">
<f:attribute name="icon" value="#{node.icon}"/>
</c:if>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
如果我将这个监听器添加到树中,则会调用onNodeSelect和getModel函数,但后来我注意到contextmenu出现了旧节点的上下文信息,然后自行消失。然后我必须再次右键单击该节点才能显示上下文菜单,此时它会正确显示并显示正确的节点信息。
<p:ajax event="select" update=":treeForm:treeMenu" listener="#{treeBean.onNodeSelect}" />
因此,从本质上讲,在我看来,支持程序化上下文菜单的功能已被破坏或根本不受支持。这是对的吗?
如何正确显示编程上下文菜单,其中包含从节点到节点的内容?
我看到的问题似乎是在上下文菜单更新之前触发了显示上下文菜单的调用,因此它以某种方式消失/被隐藏 - 然后我必须右键单击该节点再次与更新的内容重新出现。
我可能花了两天时间试图解决这个问题而无济于事。
此外,如果我添加以下调用以编程方式重新显示contextmenu,以便我不必再次右键单击它,我收到一个错误:
重新显示上下文菜单的代码,所以我不必再次点击它:
RequestContext.getCurrentInstance().execute("treeMenuWidget.show()");
错误讯息:
Uncaught TypeError: Cannot read property 'pageX' of undefined
我开始尝试以编程方式执行此操作的全部原因是因为当我尝试使用TreeNode nodeType属性和不同节点类型的不同上下文菜单时,在添加10个左右菜单后,如果我只是重新排列菜单的顺序在里面 xhtml页面然后他们将不会被分配到正确的节点,这似乎是一个错误。因此,我现在正试图以编程方式解决它,但遇到其他问题。
嗯,我想我知道问题是什么,但我还不知道如何修复它......
我在Menu.js中添加了对此JavaScript调用的提醒:
bindTree: function() {
var nodeSelector = this.jqTargetId + ' ' + (this.cfg.nodeType ? 'li.' + this.cfg.nodeType + ' .ui-tree-selectable': '.ui-tree-selectable'),
event = this.cfg.event + '.tree',
_self = this;
$(document).off(event, nodeSelector)
.on(event, nodeSelector, null, function(e) {
window[_self.cfg.targetWidgetVar].nodeClick(e, $(this));
alert(_self.cfg.nodeType);//cjr
_self.show(e);
e.preventDefault();
});
},
以下是我所看到的:
alert('root');
alert('container');
alert('list');
alert('entry');
但问题是我有这种嵌套:
nodeType=root
nodeType='container'
nodeType='list'
nodeType='entry'
nodeType='list'
因此,节点#3和#5属于同一类型,我认为因为列表nodeType已经用于节点#3,所以它不再用于节点#5,而节点#5最终用于节点#5父节点的菜单(节点#4)。
这是一个错误吗?
请告诉我如何解决问题?
顺便说一句 - 我的树正在以编程方式构建,这些数据是动态的,我没有生成,所以我无法控制列表节点可能出现嵌套的次数或任何其他节点类型。
我热切期待某人的回应...