primefaces org.primefaces.component.diagram 覆盖

primefaces org.primefaces.component.diagram override

我对 org.primefaces.component.diagram 有疑问,我想在点击任何叠加层或连接器时添加一个操作,我使用 jquery 进行此操作,但问题是没有标识符连接,搜索后我能够获得连接的 2 个端点的 ID,但如果相同点之间有很多连接,那么我无法区分它们,我试图覆盖图表并添加 "connectionId"连接上的属性,但我在前端遇到异常:

Uncaught ReferenceError: connectionId590236 is not defined at eval (eval at (jquery.js.xhtml?ln=primefaces&v=5.2:14), :1:1488) screenshot

最佳解决方案是在 DefaultDiagramModel 创建中的 Element 上使用 setId

举例如下:

    Element elementA = new Element("A", "20em", "6em");
    elementA.setId("element-a");

    Element elementB = new Element("B", "10em", "18em");
    elementB.setId("element-b");


    Element elementC = new Element("C", "40em", "18em");
    elementC.setId("element-c");
    ...

由于 PrimeFaces 不提供您正在搜索的控件,而原始组件来自 jsPlumb,您可以依靠它来实现您正在寻找的内容。

首先确保 <p:diagram> 有一个 widgetVar 值,es。 diagramWV

示例如下:

$(document).ready(function () {
  //timeout makes sure the component is initialized
  setTimeout(function () {
    for (var key in PF('diagramWV').canvas.getAllConnections()) {

        if (PF('diagramWV').canvas.getAllConnections().hasOwnProperty(key)) {

            //Elemenets Events
            // on source just once
            $(PF('diagramWV').canvas.getAllConnections()[key].source).off('click').on('click', function () {
                console.log($(this).attr('id'))
            });
            // on target just once
            $(PF('diagramWV').canvas.getAllConnections()[key].target).off('click').on('click', function () {
                console.log($(this).attr('id'))
            });

            //Connection Event
            PF('diagramWV').canvas.getAllConnections()[key].bind("click", function (conn) {
                console.log("source " + conn.sourceId);
                console.log("target " + conn.targetId);
            });
        }
    }
  }, 500);
});

注:widgetVar的canvas属性是jsPlumbInstance

的当前实例

这是在线 demo, and a small working example on github

我终于找到了一个可以接受的解决方案:

-> 在连接上添加标签覆盖并在其上设置标识符。

org.primefaces.model.diagram.Connection conn = new org.primefaces.model.diagram.Connection(
            EndPointA, EndPointB);

LabelOverlay labelOverlay = new LabelOverlay(connection.getId(), "labelOverlayClass", 0.3);
    conn.getOverlays().add(labelOverlay);

-> 然后添加 JS 函数来处理连接上的 dbclick 操作,并使用 类“._jsPlumb_overlay”和“._jsPlumb_hover 从其相关覆盖中获取 ID “

<p:remoteCommand name="connectionClicked"
    actionListener="#{yourBean.onConnectionDoubleClick}" />

<script type="text/javascript">
    var connectionId;

    $('._jsPlumb_connector').on('dblclick', function(e) {

        $('._jsPlumb_overlay._jsPlumb_hover').each(function() {
            connectionId =  $(this).text();
        });

        connectionClicked([ { name : 'connectionId', value : connectionId } ]);
    });
    });
</script>

-> 最后在 bean 中提取 id 并做任何你想做的事情

public void onConnectionDoubleClick() {
    Map<String, String> params = FacesContext.getCurrentInstance()
            .getExternalContext().getRequestParameterMap();

    String connectionId = params.get("connectionId");

    if(StringUtils.isBlank(connectionId))
        return;

    .........

我能够通过扩展 primefaces 覆盖层来向覆盖层添加点击事件 class。如果您对 toJS() class 进行更改(从 Primefaces LabelOverLay 中汲取大量灵感),那么您可以使用 jsplumb overlay constructor 编写自己的叠加层。这是我对 ClickableLabelOverlay 的实现。

public class ClickableLabelOverlay implements Overlay {
    private String label;
    private String styleClass;
    private double location = 0.5;
    private String onClick;

    public ClickableLabelOverlay() {
    }

    public ClickableLabelOverlay(String label) {
        this.label = label;
    }

    public ClickableLabelOverlay(String label, String styleClass, double location, String onClick) {
        this(label);
        this.styleClass = styleClass;
        this.location = location;
        this.onClick = onClick;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getStyleClass() {
        return styleClass;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public double getLocation() {
        return location;
    }

    public void setLocation(double location) {
        this.location = location;
    }

    public String getOnClick() {
        return onClick;
    }

    public void setOnClick(String onClick) {
        this.onClick = onClick;
    }

    public String getType() {
        return "Label";
    }

    public String toJS(StringBuilder sb) {
        sb.append("['Label',{label:'").append(label).append("'");

        if(styleClass != null) sb.append(",cssClass:'").append(styleClass).append("'");
        if(location != 0.5) sb.append(",location:").append(location);
        if(onClick != null) sb.append(",events:{click:function(labelOverlay, originalEvent){").append(onClick).append("}}");

        sb.append("}]");

        return sb.toString();
    }
}

将您想要执行的任何 javascript 放入 onClick 变量中,当您单击叠加层时它会 运行。为了方便起见,我将它添加到我的图表的默认覆盖集中。

diagram.getDefaultConnectionOverlays().add(new ClickableLabelOverlay(...)