af: panelAccordion partialtrigger on af: selectOneChoice valueChangeListener

Я новичок в лицах ADF, и у меня возникли проблемы с частичным запуском af: panelAccordion при изменении значения af: selectOneChoice. Af: panelAccordion содержит несколько af: showDetailHeader внутри af: showDetailItem. Все af: showDetailItem и их af: showDetailHeader генерируются динамически. Колледж bean находится в области видимости, и его код приведен ниже:

public class College {
    private List<Department> departments;
    private List<SelectItem> departmentDropDownMenu;
    private String selectedDepartment;

    public College() {
        this.departments = new ArrayList<Department>(0);

        Employee employee1 = new Employee("Employee 1", "Information");
        Employee employee2 = new Employee("Employee 2", "Information");
        Employee employee3 = new Employee("Employee 3", "Information");
        Employee employee4 = new Employee("Employee 4", "Information");
        Employee employee5 = new Employee("Employee 5", "Information");

        List<Employee> employees1 = new ArrayList<Employee>(0);
        employees1.add(employee1);

        List<Employee> employees2 = new ArrayList<Employee>(0);
        employees2.add(employee2);

        List<Employee> employees3 = new ArrayList<Employee>(0);
        employees3.add(employee3);

        List<Employee> employees4 = new ArrayList<Employee>(0);
        employees4.add(employee4);
        employees4.add(employee5);

        Department department1 = new Department("Department 1", employees1);
        Department department2 = new Department("Department 2", employees2);
        Department department3 = new Department("Department 3", employees3);
        Department department4 = new Department("Department 4", employees4);

        this.departments.add(department1);
        this.departments.add(department2);
        this.departments.add(department3);
        this.departments.add(department4);

        List<SelectItem> departmentDropDownMenu = new ArrayList<SelectItem>(0);
        departmentDropDownMenu.add(new SelectItem("Department 1"));
        departmentDropDownMenu.add(new SelectItem("Department 2"));
        departmentDropDownMenu.add(new SelectItem("Department 3"));
        departmentDropDownMenu.add(new SelectItem("Department 4"));

        this.setDepartmentDropDownMenu(departmentDropDownMenu);
        this.setSelectedDepartment("Department 1");
    }

    public void departmentDropDrownValueChangeListener(ValueChangeEvent event) {
        String oldValue = event.getOldValue().toString();
        String newValue = event.getNewValue().toString();

        if(oldValue.equalsIgnoreCase(newValue)) {
            return;
        }
        List<Department> departmentUpdated = new ArrayList<Department>(0);

        for (Department department : departments) {
            if(department.getDepartmentName().equals(newValue)) {
                departmentUpdated.add(department);
                break;
            }
        }

        for (Department department : departments) {
            if(!department.getDepartmentName().equals(newValue)) {
                departmentUpdated.add(department);                
            }
        }

        this.setDepartments(departmentUpdated);
    }

    public void setDepartments(List<Department> departments) {
        this.departments = departments;
    }

    public List<Department> getDepartments() {
        return departments;
    }

    public void setDepartmentDropDownMenu(List<SelectItem> departmentDropDownMenu) {
        this.departmentDropDownMenu = departmentDropDownMenu;
    }

    public List<SelectItem> getDepartmentDropDownMenu() {
        return departmentDropDownMenu;
    }

    public void setSelectedDepartment(String selectedDepartment) {
        this.selectedDepartment = selectedDepartment;
    }

    public String getSelectedDepartment() {
        return selectedDepartment;
    }
}

Классы Department и Employee представляют собой простые POJO. Класс «Отдел» содержит только два поля: 1. Строковое имя отдела и 2. Список сотрудников с их методами доступа. Класс «Сотрудник» также содержит два поля: 1. Строковое имя и 2. Строковая информация.

Код страницы в формате jspx приведен ниже:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="Page.jspx" id="d1">
            <af:form id="f1">
                <af:panelStretchLayout id="psl1">
                    <f:facet name="center">
                        <af:panelGroupLayout id="pgl2">
                            <af:selectOneChoice label="Department" value="#{college.selectedDepartment}" id="soc1"
                                                unselectedLabel="" autoSubmit="true" immediate="true"
                                                valueChangeListener="#{college.departmentDropDrownValueChangeListener}">
                                <f:selectItems value="#{college.departmentDropDownMenu}" id="si1"/>
                            </af:selectOneChoice>
                            <af:panelAccordion id="pa1" discloseNone="true" partialTriggers="soc1" discloseMany="true">
                                <af:forEach items="#{college.departments}" var="department">
                                    <af:showDetailItem text="#{department.departmentName}" id="sdi1">
                                        <af:forEach items="#{department.employees}" var="employee">
                                            <af:showDetailHeader text="#{employee.name}" disclosed="false" id="sdh1">
                                                <af:outputText value="#{employee.info}" id="ot1"/>
                                            </af:showDetailHeader>
                                        </af:forEach>
                                    </af:showDetailItem>
                                </af:forEach>
                            </af:panelAccordion>
                        </af:panelGroupLayout>
                    </f:facet>
                </af:panelStretchLayout>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Я хочу изменить порядок af: showDetailItem в зависимости от выбранного значения af: selectOneChoice.

Я показываю проблему на изображениях: Изображение 1 Изображение 2

Как видите, первое изображение - нормальное состояние после загрузки страницы. В отделе 1 есть только один сотрудник, а именно, у сотрудника 1 и у подразделения 4 есть два сотрудника Сотрудник 1, сотрудник 2. После выбора отдела 4 из раскрывающегося списка, отдел 3 переходит на последнюю позицию, но там, на панели отдела 3, очевидно, два af: showDetailItem в фотография, но изначально в ней всего один сотрудник. Кроме того, дополнительный af: showDetailItem не активен.

Если кто-нибудь, пожалуйста, дайте какое-либо предложение, это будет мне очень полезно.

Спасибо.


person Tapas Bose    schedule 03.12.2011    source источник


Ответы (1)


Проблема в использовании <af:forEach/>. Согласно документации тега:

Объекты в элементах тега <af:forEach> нельзя добавлять, удалять или переупорядочивать после создания дерева компонентов.

Вместо этого вы можете использовать тег <af:iterator/>. JDev будет жаловаться, что это недействительный дочерний элемент <af:panelAccordion/>, но он работает.

Этот макет страницы, кажется, работает. Обратите внимание, я переместил <af:selectOneChoice/> на верхний фасет и сбросил <af:panelGroupLayout/>, чтобы заставить аккордеон растянуться и сделать всех дочерних элементов видимыми.

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="Page.jspx" id="d1">
            <af:form id="f1">
                <af:panelStretchLayout id="psl1">
                    <f:facet name="center">
                            <af:panelAccordion id="pa1" discloseNone="false" partialTriggers="soc1" discloseMany="true" reorder="enable">
                                <af:iterator value="#{college.departments}" var="department">
                                    <af:showDetailItem text="#{department.departmentName}" id="sdi1">
                                        <af:iterator value="#{department.employees}" var="employee">
                                            <af:showDetailHeader text="#{employee.name}" disclosed="false" id="sdh1">
                                                <af:outputText value="#{employee.info}" id="ot1"/>
                                            </af:showDetailHeader>
                                        </af:iterator>
                                    </af:showDetailItem>
                                </af:iterator>
                            </af:panelAccordion>    
                    </f:facet>
                    <f:facet name="top">
                        <af:selectOneChoice label="Department" value="#{college.selectedDepartment}" id="soc1" unselectedLabel="" autoSubmit="true"
                                            valueChangeListener="#{college.departmentDropDrownValueChangeListener}" immediate="true">
                            <f:selectItems value="#{college.departmentDropDownMenu}" id="si1"/>
                        </af:selectOneChoice>
                    </f:facet>
                </af:panelStretchLayout>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Надеюсь это поможет. Приветствуем беспорядок, который представляет собой ADF. :)

person Billy Bob Bain    schedule 14.12.2011