JSF / primefaces在图元素中发生事件

时间:2016-03-05 09:58:17

标签: jsf jsf-2 primefaces managed-bean

我需要在点击这个元素时访问managedBean中的org.primefaces.model.diagram.Element的数据对象。我正在使用primefaces 5.2。 我尝试了多种方法来建立这个,但到目前为止没有一个方法可行。这是一种方法:

XHTML:

的想法是,通过commandLink操作属性传递元素(对于例如数据表,它可以正常工作):

 <fl:composition template="/WEB-INF/template.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:fl="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
   <fl:define name="content">
      <h:form id="form">
         <p:diagram style="height:600px" value="#{flowDiagramBean.model}" var="el">
            <f:facet name="element">
               <p:commandLink actionListener="#{flowDiagramBean.onElementClicked}" update="@form" value="#{el.actionElementLabelText}">
                  <f:attribute name="element" value="#{el}"/>
               </p:commandLink>
            </f:facet>
         </p:diagram>
      </h:form>
   </fl:define>
</fl:composition>

原型图的初始构建:

@PostConstruct
   public void init() {
      setModel(new DefaultDiagramModel());
      getModel().setMaxConnections(-1);

      getModel().getDefaultConnectionOverlays().add(new ArrowOverlay(20, 20, 1, 1));
      FlowChartConnector connector = new FlowChartConnector();
      connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:3}");
      getModel().setDefaultConnector(connector);

      ScreenFlowItemObj screenFlowItemObj = new ScreenFlowItemObj();
      screenFlowItemObj.setActionElementLabelText("test");

      Element start = new Element(screenFlowItemObj, "20em", "6em");
      start.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
      start.addEndPoint(new BlankEndPoint(EndPointAnchor.LEFT));

      Element trouble = new Element(screenFlowItemObj, "20em", "18em");
      trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.TOP));
      trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.BOTTOM));
      trouble.addEndPoint(new BlankEndPoint(EndPointAnchor.RIGHT));

      model.addElement(start);
      model.addElement(trouble);

   }

如您所见,ScreenFlowItemObj类型是每个元素的传递数据对象。

actionListener如下所示:

public void onElementClicked(ActionEvent event) {
      ScreenFlowItemObj screenFlowItemObj = (ScreenFlowItemObj) event.getComponent().getAttributes().get("element");
   }

不幸的是,单击commandLink时,属性“element”不会被放到属性映射中,因此在侦听器中,screenFlowItemObj会解析为null。难道我做错了什么?可能还有另一种方法可以实现这一目标吗?

我在使用JSF 2.2的1.7 tomee上使用primefaces 5.2。

谢谢,

贡纳尔

2 个答案:

答案 0 :(得分:2)

在PrimeFaces使用的jsPlumb框架中,'elements'上没有click事件,因此无法直接执行'ajax'选择事件。

你能做的是:

  1. 在模型中为每个元素指定一个显式ID(例如start.setId('start'))
  2. 在图表后面的图中添加一些代码,将事件处理程序添加到图元素中(这些可以通过类来识别(`ui-diagram-element)
  3. 在事件处理程序中调用一个PrimeFaces远程命令,该命令调用一个actionListener,其中添加了被点击元素的id
  4. 添加eventhandler:

    $(document).on('click', '.ui-diagram > .ui-diagram-element', function(info){
      console.log(info.target.id); // change this to call the remote command
    });
    

    如何将info.target.id传递给远程命令,可以在this stackoverflow Q/A中读取

    我检查了第1步和第2步并使用了之前的3。这一切都有效,我还没有将它们合并,但这应该不是困难的

答案 1 :(得分:1)

感谢Kukeltje方法,我能够成功实施功能性再求:

XHTML:

<fl:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:fl="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <fl:define name="content">
        <h:form id="screenFlowForm">
            <p:diagram value="#{flowDiagramBean.model}" var="el"
                style="height:600px">
                <f:facet name="element">
                    <h:outputText value="#{el.actionElementLabelText}" />
                </f:facet>
            </p:diagram>
            <p:remoteCommand name="elementClicked"
                actionListener="#{flowDiagramBean.onElementClicked}"/>
            <script type="text/javascript">
                        $(document).on('click',
                                '.ui-diagram > .ui-diagram-element',
                                function(info) {
                                    elementClicked([ {
                                        name : 'elementId',
                                        value : info.target.id
                                    } ]);
                                });
            </script>
        </h:form>
    </fl:define>
</fl:composition>

的ActionListener:

public void onElementClicked() {
        logger.info(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("elementId"));
    }

适合我。我不明白,为什么我必须在一个单元素数组中传递参数,但确定 - 它正在工作。

感谢您带领我走向正确的方向。

贡纳尔