1

我确实有非常简单的域结构 - 包含可选项目(复选框)的组。不可能从不同的组中选择项目。它以某种方式失去状态并且表现不稳定..为什么?我究竟做错了什么?

素面3.5

上课..

@ManagedBean
@SessionScoped
public class IssueDescription {

  private List<Item> items = new ArrayList<>();

  public List<Item> getItems() {
    return items;
  }
}

public class Group {

  private String id;
  private String name;
  private List<Item> items = new ArrayList<>();

  // getters, setters, equals hashCode..
}

public class Item {

  private String id;
  private String name;
  private Group group;

  // getters, setters, equals hashCode..
}

@ViewScoped
@ManagedBean(name = "example")
public class CheckboxesExample {

  @ManagedProperty("#{issueDescription}")
  private IssueDescription issueDescription;

  private List<Group> groups = new ArrayList<>();
  private List<Item> selectedItems = new ArrayList<>();

  private boolean selectedConditionRemoved;
  private Item selectedItem;

  private Map<String,Item> allItems = new HashMap<>();

  @PostConstruct
  public void prepare() {
    Group colors = Group.create("1", "Colors");
    colors.getItems().add(Item.create("00110", "yellow", colors));
    colors.getItems().add(Item.create("00120", "red", colors));

    Group materials = Group.create("2", "Materials");
    materials.getItems().add(Item.create("00130", "iron", materials));
    materials.getItems().add(Item.create("00140", "sand", materials));

    Group conditions = Group.create("3", "Vehicles");
    conditions.getItems().add(Item.create("00150", "broken", conditions));
    conditions.getItems().add(Item.create("00160", "OK", conditions));
    conditions.getItems().add(Item.create("00170", "fixable", conditions));

    groups.add(colors);
    groups.add(materials);
    groups.add(conditions);

    selectedItems.addAll(getIssueDescription().getItems());

    for (Group group : getGroups()) {
      for (Item item : group.getItems()) {
        allItems.put(item.getId(), item);
      }
    }
  }

  public void listener(AjaxBehaviorEvent event) {
    if (isSelectedConditionRemoved()) {
      getIssueDescription().getItems().remove(getSelectedItem());
    }
    else {
      if (!getIssueDescription().getItems().contains(getSelectedItem())) {
        getIssueDescription().getItems().add(getSelectedItem());
      }
    }

    RequestContext.getCurrentInstance().update(Arrays.asList("selectedConditions"));
  }

  // Thanks to BalusC..
  public void updateItems(ValueChangeEvent event) {

    // lets figure out which item was selected or deselected

    List<Item> oldValue = (List<Item>) event.getOldValue();
    List<Item> newValue = (List<Item>) event.getNewValue();

    if (oldValue == null) {
      oldValue = Collections.emptyList();
    }

    if (oldValue.size() > newValue.size()) {
      oldValue = new ArrayList<>(oldValue);
      oldValue.removeAll(newValue);
      selectedItem = oldValue.iterator().next();
      selectedConditionRemoved = true;
    }
    else {
      newValue = new ArrayList<>(newValue);
      newValue.removeAll(oldValue);
      selectedItem = newValue.iterator().next();
      selectedConditionRemoved = false;
    }

    findNamesForSelectedConditions();
  }

  private void findNamesForSelectedConditions() {
    if (getSelectedItem() != null && allItems.containsKey(getSelectedItem().getId())) {
      Item item = allItems.get(getSelectedItem().getId());
      getSelectedItem().setName(item.getName());
    }
  }

  public boolean isSelectedItemsContainerVisible() {
    return !getIssueDescription().getItems().isEmpty();
  }

  public List<Item> getItems() {
    return getIssueDescription().getItems();
  }

  // .. getters and setters
  }
}

@FacesConverter(forClass = Item.class)
@ManagedBean(name = "conditionConverter")
public class ConditionConverter implements Converter {

  private static final String DELIMITER = "__";

  @Override
  public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
    String[] fields = value.split(DELIMITER);

    Item c = (Item) Item.create(fields[1]);

    Group group = new Group();
    group.setId(fields[0]);
    group.getItems().add(c);

    c.setGroup(group);

    return c;
  }

  @Override
  public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
    Item item = (Item) o;

    StringBuilder sb = new StringBuilder();

    sb.append(item.getGroup().getId());
    sb.append(DELIMITER);
    sb.append(item.getId());

    return sb.toString();
  }
}

和 XHTML..

<ui:repeat value="#{example.groups}" var="group">
    <ul>
        <li>
            <h:outputText value="#{group.name}"/>

            <p:selectManyCheckbox layout="pageDirection"
                                  converter="#{conditionConverter}"
                                  value="#{example.selectedItems}"
                                  valueChangeListener="#{example.updateItems}">

                <f:selectItems value="#{group.items}"/>

                <p:ajax listener="#{example.listener}" />
            </p:selectManyCheckbox>
        </li>
    </ul>
</ui:repeat>
4

0 回答 0