JSF динамическая загрузка почти работает - но без командных кнопок - PullRequest
2 голосов
/ 16 июля 2011

Я хочу динамически включать файлы .xhtml во время выполнения, что вы могли бы назвать интерфейс JSF к иерархии наследования на уровне объекта. Я жду иметь в общей сложности 100 x 30-50 строк xhtml файлов, которые будут загружены только если требуется, чтобы правильно обрабатывать базовые данные. Типичный вариант использования что для работы с основными данными потребуется один или два файла xhtml, так что вы можете себе представить, что я не хочу загружать все 100 каждый раз, это будет быть преступно глупым для этого.

Теперь я знаю, что существуют бесконечные дискуссии на эту тему, но после бесчисленных часов исследований я попал точно в никуда. я использую Мохарра 2.1.1.

В приведенном ниже примере я изначально ui: включить «пустой» файл, файл с минимальный контент (вместо c: catch), затем нажмите кнопку command, которая изменяет содержимое для включения в new.xhtml и обновляет контейнер интерфейса: включите с AJAX.

Содержимое файла new.xhtml отображается на странице, поэтому это выглядит хорошо. проблема в том, что у меня есть commandButton в new.xhtml, и когда этот файл динамически включен commandButton не будет работать - подпрограмма действия никогда не называется. Если вы используете пользовательский интерфейс: включите new.xhtml (вместо # {bean.page}) это работает отлично. Итак, несколько вопросов:

  1. Кто-нибудь еще работает?
  2. Если нет, то есть ли другой способ сделать это?
  3. Почему что-то невероятно очевидное и полезное так сложно сделать?

Сегодня я поиграл с jQuery load (), и пока я могу загружать файлы, используя его Есть разные проблемы. Файлы, которые я хочу загрузить, будут содержать PrimeFaces диалоги и при загрузке jQuery диалоги, казалось, на мгновение вспыхивают на экране, прежде чем исчезнуть, навсегда, в пропасть. Другие сообщают компоненты, не имеющие CSS-стиля.

Спасибо.

Редактировать: я должен дать понять, что мое желание делать динамическую загрузку, а не просто перейти на другую страницу, потому что я просто хочу использовать диалоги Primefaces, другой в зависимости от типа основных данные. Это был бы более аккуратный способ сделать это, если это возможно.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h:commandButton value="push" action="#{bean.doit}">
                <f:ajax render="load"/>
            </h:commandButton>
            <br/>
            <h:panelGroup id="load">
                <ui:include src="#{bean.page}"/>
                <ui:remove>
                <ui:include src="new.xhtml"/>
                </ui:remove>
            </h:panelGroup>
        </h:form>
    </h:body>
</html>

new.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core">
    <h:outputText value="new.xhtml"/>
    <br/>
    <h:commandButton value="inc" action="#{bean.inc}">
        <f:ajax/>
    </h:commandButton>
</html>

empty.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"/>

Bean.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Bean {

    private String page = "/empty.xhtml";

    public String doit() {
        page = "/new.xhtml";
        return null;
    }
    // getters & setters removed
}

Ответы [ 2 ]

3 голосов
/ 20 июля 2011

Проблема заключается в том, что пользовательский интерфейс ui: include реализован обработчиком тегов, который выполняется во время просмотра восстановления и не выполняется повторно во время вызова приложения, поэтому при изменении дерева компонентов логика приложения не знает об изменениях,Это верно только при использовании частичного сохранения состояния.

Я скопировал код из обработчика тегов пользовательского интерфейса: include в очень простой пользовательский компонент и мог, по крайней мере, заставить методы действий запускаться, но не надежно.

Решение состоит в том, чтобы исключить представления, требующие этого динамического пользовательского интерфейса: включить функциональность при использовании частичного сохранения состояния с записью в web.xml, например:

<context-param>
  <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
  <param-value>/index.xhtml</param-value>
</context-param>

Это было проверено с использованием нескольких командных кнопок в нескольких включенныхфрагменты страницы и, кажется, работают надежно (протестировано с bean-компонентами ViewScoped JSF).Я также динамически включил файл, содержащий диалоги простых лиц, и это тоже хорошо работает.Я надеюсь, что это будет полезно для других, поскольку это заняло много времени из моего графика, но, по крайней мере, сейчас оно работает, и это хорошо.

Приветствия.

1 голос
/ 17 июля 2011

Можно сказать, что идея JSF состоит в том, что уровень представления имеет свой собственный стек MVC внутри: каждый компонент иерархии представления действует как контроллер (читает данные запроса), модель (сохраняет свое состояние) и представление (визуализирует себя) ). Для этого необходимо, чтобы представление было стабильным: представление, обрабатывающее запросы, должно быть таким же, как представление, которое отображало форму. Трудно рассуждать об изменениях в дереве представлений, которые происходят в середине жизненного цикла.

В вашем случае проблема, вероятно, (я не проверял) в том, что bean-компонент имеет область действия запроса, поэтому свойство страницы устанавливается в "/new.xhtml", пока кнопка отображается, но когда действие от кнопки При отправке обратно на сервер свойство снова имеет значение «/empty.xhtml», поэтому кнопка не существует в воссозданном представлении, поэтому она не распознает действие и не выполняет его. Может помочь изменение области действия компонента на @ViewScoped.

Что касается "Почему что-то невероятно очевидное и полезное так сложно сделать?" - мне кажется, судя по вопросу, что вы сделали какой-то важный и сомнительный архитектурный проект, БЕЗ следуя какой-либо установленной практике JSF и БЕЗ изучения библиотеки, для которой вы проектировали (вы читали документацию? или только примеры?), основываясь на том, как библиотека должна работать. Я думаю, что какой-то позор был бы более уместным, чем критика и требования.

...