Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > jsf как работать с деревом объектов?


Автор: leniviy 18.9.2010, 12:29
Видимо я какой-то паттерн не знаю.
Есть дерево объектов с трехуровневой структурой: репортБин/группа/репорт.
Элементы рисую внутри c:foreach, операции через h:commandLink.
С добавлением элементов в репортБин проблем нет.
Долго думал, как сделать удаление и добавление в дочерний объект, поскольку вызвать действие можно только без параметров, но надо знать, с каким именно объектом работаю.
(ну я пробовал f:attribute и f:param, но там были другие заморочки)
Решил, что надо сделать для дочерних объектов inner class и объявить действия в них.
Это работало с двухуровневой структурой, а дальше полезли ошибки. Например, если я жму на ссылки "(remove)" начиная с верхней, то на третьем удалении вылезает это:
Код

javax.servlet.ServletException: #{report.doRemove}: javax.el.PropertyNotFoundException: /pages/reports.xhtml @22,85 
action="#{report.doRemove}": Target Unreachable, identifier 'report' resolved to null

А если снизу вверх, то ничего.

Код

package foo;

import java.util.*;

public class ReportsBean {
    public class Group {
        public class Report {
            public void doRemove() {
                reports.remove(this);
            }
        }
        private List<Report> reports;
        public Group() {
            reports = new ArrayList<Report>();
            reports.add(new Report());
            reports.add(new Report());
        }
        
        public void doRemove() {
            groups.remove(this);
        }

        public void setReports(List<Report> reports) {this.reports = reports;} public List<Report> getReports() {return reports;}
    }
    private List<Group> groups;
    
    public void reset() {
        groups = new ArrayList<Group>();
        groups.add(new Group());
        groups.add(new Group());
    }
    public ReportsBean() {
        reset();
    }
    public void doReset() {reset();}
    public void setGroups(List<Group> groups) { this.groups = groups;} public List<Group> getGroups() {return groups;}
}


reports.xhtml:
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:c="http://java.sun.com/jstl/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:rich="http://richfaces.org/rich">
      <head>
</head>
<body background="#{facesContext.externalContext.requestContextPath}/img/barricade.gif" >

<h:form>
<h:commandLink value="reset1" action="#{reportsBean.doReset}"/><br/> 
<hr/>
<ul>
<c:forEach items="#{reportsBean.groups}" var="group">

  <li>#{group}
  <!--  <h:commandLink value="(remove)" action="{group.doRemove}"/> -->
  <ul>
    <c:forEach items="#{group.reports}" var="report">
    <li>#{report} <h:commandLink value="(remove)" action="#{report.doRemove}"/></li>
    </c:forEach>
  </ul>
  </li>
</c:forEach>
</ul>
</h:form>
</body>
</html>


джарники:
Код

common-annotations.jar
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-lang-2.4.jar
commons-logging.jar
el-ri.jar
jsf-api.jar
jsf-facelets.jar
jsf-impl.jar
jsf-tlds.jar
richfaces-api-3.3.3.Final.jar
richfaces-impl-3.3.3.Final.jar
richfaces-ui-3.3.3.Final.jar

Автор: leniviy 21.9.2010, 09:34
Почитал про postback. Оказалось, что конструкции <c:set>/<c:foreach> итд работают 1 раз при построении дерева компонентов.
Мое действие модифицирует дерево объектов в бине, а дерево компонентов остается прежним. Отсюда глюки.
Пришлось заменить теги по принципу:

  •  <c:foreach>          -> <ui:repeat>
  •  <c:set>              -> <ui:param>
  •  <c:if test="#{foo}"> -> <h:panelGroup rendered="#{foo}">
  •  <h:selectOneMenu><c:forEach>... -> <t:selectOneMenu>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)