问题
I am having a primefaces Tree in a dialog. When I make selections in the Tree and click Add button, it adds all selections to a "p:selectManyMenu" in another panel. Code for the Dialog and Tree:
<h:form id="categoriesDialogForm">
<p:dialog id="categoriesDialog" header="Add a Category" widgetVar="categoriesDialogVar" closeOnEscape="true" height="500" resizable="false" >
<p:panelGrid>
<p:row>
<p:column>
<p:tree id="categoriesTree" value="#{searchController.categoriesTree}" var="node" selectionMode="checkbox" style="width : auto;" selection="#{searchController.selectedCategories}" propagateSelectionDown="false" propagateSelectionUp="false">
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
</p:column>
</p:row>
</p:panelGrid>
<f:facet name="footer">
<div align="center">
<p:commandButton value="Add" style="font-size: 0.8em;" action="#{searchController.addCategory()}" update=":advSearchForm:subCatPanel"/>
</div>
</f:facet>
</p:dialog>
</h:form>
So far it works fine. Now when I make selections in the ManyMenu and click remove button, it removes the selected categories from the backing bean "searchController.selectedCategories" and updates the dialog. Code for remove button:
<p:commandButton value="Remove" style="font-size : 0.9em;" action="#{searchController.removeCategory()}" update=":categoriesDialogForm:categoriesTree"></p:commandButton>
Code for removeCategory Java method
public void removeCategory() {
//Updating the selectedSubjectSet collection
//removeSubjects is a Set for which the node selection should be removed
for (String subToRemove : removeSubjects) {
selectedSubjectSet.remove(subToRemove);
}
//Rebuilding the array of selections
//selectedSubjectSet is a Set whose selections in the Tree should remain
List<TreeNode> result = new ArrayList<>();
for (TreeNode t : selectedCategories) {
if (selectedSubjectSet.contains(t.getData().toString())) {
result.add(t);
}
}
selectedCategories = result.toArray(new TreeNode[result.size()]);
removeSubjects.clear();
}
But when I open the dialog again, the previous selections persist. I am sure that the "searchController.selectedCategories" is updated but the selections in the Tree dont get updated. I also tried setting the "searchController.selectedCategories" value to null in remove button's action but the old values still persist. Not sure what is wrong. Am I doing something wrong?
回答1:
We have to update both the selection array and also the Tree for it to reflect the changes. The removeCategory() should have the following:
public void removeCategory() {
//Updating the selectedSubjectSet collection
//removeSubjects is a Set for which the node selection should be removed
for (String subToRemove : removeSubjects) {
selectedSubjectSet.remove(subToRemove);
}
//Rebuilding the array of selections
//selectedSubjectSet is a Set whose selections in the Tree should remain
List<TreeNode> result = new ArrayList<>();
for (TreeNode t : selectedCategories) {
if (selectedSubjectSet.contains(t.getData().toString())) {
result.add(t);
}
}
selectedCategories = result.toArray(new TreeNode[result.size()]);
//Updating the Tree for selections
//Need to iterate the Level 2 Nodes as well
List<TreeNode> tree = categoriesTree.getChildren();
for (TreeNode node : tree) {
String subject = (String) node.getData();
if (removeSubjects.contains(subject)) {
node.setSelected(false);
}
List<TreeNode> subTree = node.getChildren();
for (TreeNode subNode : subTree) {
subject = (String) subNode.getData();
if (removeSubjects.contains(subject)) {
subNode.setSelected(false);
}
}
}
removeSubjects.clear();
}
来源:https://stackoverflow.com/questions/24740324/primefaces-4-0-tree-selection-update-in-backing-bean-does-not-work