Good day! I do a composite component on jsf using primefaces. My component:

<composite:interface componentType="com.bean.lazyTreeTable"> <composite:attribute name="xmlFilePath"/> </composite:interface> <composite:implementation> <span id="#{cc.id}" class="ltt-mainForm"> <h:form prependId="false"> <f:event listener="#{cc.createTree(cc.attrs.xmlFilePath)}" type="preRenderComponent"/> <p:growl styleClass="ltt-messages" showDetail="true" /> <p:commandButton value="Наверх" styleClass="ltt-homeButton" icon="ui-icon-carat-1-n" actionListener="#{cc.toHome}" update="@(.ltt-treeTable)" oncomplete="scrollableUpdate(); scrollToHome();" /> <p:remoteCommand name="refreshTree" update="@(.ltt-treeTable)" actionListener="#{cc.onScroll}" oncomplete="scrollableUpdate(); refreshScrollPosition();" /> <p:remoteCommand name="updateTree" update="@(.ltt-treeTable)" oncomplete="scrollableUpdate(); scrollToExpandedNode();" /> <p:treeTable value="#{cc.root}" var="xmlNode" styleClass="ltt-treeTable" id="ltt_treeTable" emptyMessage="Не загружен файл для отображения" scrollable="true" scrollHeight="500"> //событие раскрытия узла <p:ajax event="expand" listener="#{cc.onNodeExpand}" onstart="setExpandedNode();" oncomplete="updateTree();"/> <p:ajax event="collapse" listener="#{cc.onNodeCollapse}" onstart="setExpandedNode();" oncomplete="updateTree();" /> <f:facet name="header"> <h:outputText value="#{cc.xmlFileName}"/> <br /> <div class="ltt-searchPanel"> <h:outputLabel for="textForSearch" value="Текст для поиска:" style="font-weight:bold" /> <p:inputText classStyle="ltt-textForSearch" id="textForSearch" value="#{cc.textForSearch}" onchange="clearSearchParams();"/> <p:commandButton value="Искать далее" id="searchButton" icon="ui-icon-search" onclick="searchText();"/> <p:remoteCommand name="searchTextInOtherPages" update="@(.ltt-treeTable), @(.ltt-messages)" actionListener="#{cc.search}" oncomplete="scrollableUpdate(); scrollToSearchedNode();" /> <h:inputHidden class="ltt-searchedNodeID" value="#{cc.searchedNodeID}"/> </div> </f:facet> <p:column headerText="Узел" style="width: 20%"> <fieldset class="ltt-textPanel"> <div class="ltt-nameValue" >#{xmlNode.name}</div> <div class="ltt-namespaceValue" >#{xmlNode.namespace}</div> <div class="ltt-idValue">#{xmlNode.identifier}</div> </fieldset> </p:column> <p:column headerText="Атрибуты" style="width: 20%; padding: 0px"> <p:dataList value="#{xmlNode.attributes}" var="xmlAttribute" emptyMessage="" styleClass="ltt-attributeList"> <table class="ltt-attributeTable"> <tr> <td style="width: 30%"> <div class="ltt-textValue">#{xmlAttribute.name}</div> </td> <td> <div class="ltt-textValue">#{xmlAttribute.value}</div> </td> </tr> </table> </p:dataList> </p:column> <p:column headerText="Значение"> <div class="ltt-textValue">#{xmlNode.value}</div> </p:column> </p:treeTable> </h:form> </span> </composite:implementation> 

On the server I process the opening of the tree node:

 public void onNodeExpand(NodeExpandEvent event) throws XMLStreamException { TreeNode currentNode = (TreeNode) event.getTreeNode(); int id = ((XmlNode) currentNode.getData()).getIdentifier(); root = service.expandOrCollapseNode(id); } 

I get currentNode null. If you do not use the composite component, then everything works. Tell me where I am wrong.

  • Make sure that there are no nested forms, if the composite contains a form, then its connection on the page should be outside the form. In general, the well-known JSF guru - BalusC - recommends not using composites unnecessarily and recommends using ui: include instead if there are no obstacles to this (ui: include can be parameterized with ui: param). The presence of the form inside your component hints that the content is not the most suitable for the design as a composite. - bobzer
  • The presence of the form is my mistake =) - Alexey

1 answer 1

Understood! The fact is that the service variable is reset with each new request to the server. In order to save it, you can use the method

getStateHelper().put("service", service)

You can get the method

getStateHelper().eval("service", null)

For correct storage, the type of the variable must be serializable.