Отсутствующие значения параметров в вызываемом методе с составными компонентами с использованием ui: repeat

Итак, после нескольких дней отладки мы в конечном итоге смогли воспроизвести некоторые странные взаимодействия между составными компонентами,ui:repeat, p:remoteCommand и частичное сохранение состояния в JSF, которое мы не понимаем.

сценарий

составной компонент перебирает список объектов с помощью ui:repeat. Во время каждой итерации включается другой составной компонент и передаются аргументы.

<ui:composition (...)>
  <ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
    <namespace:myRemoteCommand someParam="SomeParam"/>

в включенном составном компоненте, там это автоматический запуск p:remoteCommand вызов метода с использованием параметров, определенных в интерфейсе компонента.

<ui:component (...)>
  <p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
                   autoRun="true"
                   async="true"
                   global="false">

Впрочем, при установке точки останова в someMethod(...), передается пустая строка. Это происходит только если частичное сохранение состояния установлено значение false.

решений

мы попробовали несколько решений, и следующие, похоже, работают (однако мы не понимаем, почему и не можем предвидеть никаких дальнейших проблем, которые могли бы occur):

  • мы можем установить частичное сохранение состояния на true.

  • мы можем изменить шаблон составного компонента на ui:include.

  • мы можем удалить один или оба составных компонента и напрямую включить содержимое.

вопрос

почему JSF ведет себя таким образом? Что это за взаимодействие между составными компонентами,ui:repeat и аргумент, передающий эти изменения, зависит от того, используем ли мы ui:include / частичное сохранение состояния или нет?

мы используем Primefaces 5.3, Glassfish 4.1, Mojarra 2.2.12, Java 8.

1 ответов


ваш код в порядке. Это просто, что Mojarra по <ui:repeat> сломан. Вы не первый, кто сталкивается с проблемой управления государством, связанной с <ui:repeat>.

основной причиной вашей проблемы является то, что #{cc} нигде не доступен в данный момент <ui:repeat> необходимо посетить дерево. Эффективно,<ui:repeat value> is null. Быстро обойти это чтобы явно нажать #{cc} на UIRepeat#visitTree() метод. Учитывая Mojarra 2.2.12, добавьте ниже строки прямо перед строка 734 С pushComponentToEL(facesContext, null).

UIComponent compositeParent = getCompositeComponentParent(this);
if (compositeParent != null) {
    compositeParent.pushComponentToEL(facesContext, null);
}

и добавить ниже строки сразу после строка 767 С popComponentFromEL(facesContext).

if (compositeParent != null) {
    compositeParent.popComponentFromEL(facesContext);
}

если вы не создаете Mojarra из источника, скопируйте весь исходный код of UIRepeat в ваш проект, сохраняя его структуру пакета и применять выше изменения на нем. Классы в /WEB-INF/classes имеют более высокий приоритет загрузки классов, чем в /WEB-INF/lib и . Я, по крайней мере, создал вопрос 4162 для решения этой проблемы.

альтернативой является замена Mojarra на MyFaces или замена <ui:repeat> на UIData на основе компонента, который получил право государственного управления, такие как <h:dataTable> или <p:dataList>.

<p:dataList type="none" var="myVar" value="#{cc.attrs.controller.someList}">
    <namespace:myRemoteCommand someParam="SomeParam" />
</p:dataList>

вы можете только применить некоторые CSS, чтобы избавиться от стиля виджета( границы и тому подобное), но это тривиальные.

Читайте также: