Обновление списка JSF через Ajax некорректно - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь перенести некоторые функции из JQuery в JSF и получаю странные результаты.

По сути, это страница, на которой вы можете перемещаться по ссылкам (представьте, как Windows Explorer в Интернете).Папки имеют ссылку, а листы - нет.Чтобы построить это, он использует private List<Element> list;, который обновляется соответственно.Поэтому, когда пользователь нажимает на «папку», создается новое list с содержимым этой папки.

Проблема в том, что я получаю странные результаты.Иногда я перемещаюсь по ссылке, и она обновляется правильно, но в некоторых случаях она ведет себя так, как будто страница перезагружается (но это не так), и list сбрасывается к своим начальным значениям (?).Например, я перехожу к «name2» и получаю правильные вещи.Но затем я перехожу к «name2b» и вместо листьев я получаю «name1», «name2» и «name3», которые устанавливаются только в методе init().Я не знаю, как это происходит, но, изучая исходный код, кажется, что структура c:foreach работает с идентификаторами, и на странице отображается старый идентификатор (обратите внимание, что я пробовал ui:repeat с такими же неверными результатами).

Как это исправить?

Это упрощенный код:

<f:metadata>
   <f:viewAction action="#{controller.init}" />
</f:metadata>
...
<h:panelGroup id="visor" layout="block">
            <ul>
                <c:forEach items="#{controller.list}" var="element">
                    <li>
                        <ui:fragment rendered="#{element.folder}">
                            <h:form>
                                <h:commandButton action="#{controller.navigate(element.name)}" type="submit" value="#{element.name}" >
                                    <f:ajax render="visor" execute="@this" />
                                </h:commandButton>
                            </h:form>
                        </ui:fragment>
                        <ui:fragment rendered="#{not element.folder}">
                            <span>#{element.name}</span>
                        </ui:fragment>
                    </li>
                </c:forEach>
            </ul>
        </h:panelGroup>

И контроллер

@Named(value = "controller")
@ViewScoped
public class MyController implements Serializable {

private List<Element> list;

public void init() { //Called when loading the page
    list = new ArrayList<>();
    Element e1 = new Element("name1", true); //name and isFolder?
    Element e2 = new Element("name2", true);
    Element e3 = new Element("name3", true);
    list.add(e1);
    list.add(e2);
    list.add(e3);
}

public void navigate(String name) {
    list = new ArrayList<>();
    if (name.equals("name1")) {
         Element e1 = new Element("name1a", true);
         Element e2 = new Element("name1b", true);
         Element e3 = new Element("name1c", true);
         list.add(e1); list.add(e2); list.add(e3);
    } else if (name.equals("name2")) {
        Element e1 = new Element("name2a", true);
         Element e2 = new Element("name2b", true);
         Element e3 = new Element("name2c", true);
         list.add(e1); list.add(e2); list.add(e3);
    } else {
        Element e1 = new Element("leaf1", false);
         Element e2 = new Element("leaf2", false);
         list.add(e1); list.add(e2);
    }
}
//....

РЕДАКТИРОВАТЬ

Кажется, моя проблема описана здесь .

Мне нужно выяснить, может ли этот вопрос пролить светк теме.

1 Ответ

0 голосов
/ 07 июня 2018

Очевидно, это хорошо известная вещь , что моя структура не может динамически обновляться в JSF.Решение, которое я должен сделать, это использовать h:datatable вместо <ul> списка (это одна вещь, которая мне действительно не нравится в JSF, но я не уверен, как визуализировать список с базовым JSF- вместо таблицы, которую я могу динамически обновлять.

Атрибут Ajax render должен был указывать form id.

<h:form id="visor">
      <h:dataTable value="#{controller.list}" var="element">
                    <h:column>
                        ....
                        <h:commandButton action=.... >
                          <f:ajax render="visor" execute="@this" />
                        </h:commandButton>
                        ....
                    </h:column>
      </h:dataTable>
</h:form>

Редактировать :UL также работал, пока я рендерил форму, а форма содержит все

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...