Отсутствующие значения параметров в вызываемом методе с составными компонентами с использованием 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>
.
- флажок внутри пользовательского интерфейса: повторить не обновляется Ajax
- динамически добавленное поле ввода в ui: повтор не обрабатывается во время отправки формы
- компоненты имеют один и тот же идентификатор внутри ui:repeat
- теги
- составной компонент с пользовательским компонентом поддержки странно ломается при вложении внутри ui: repeat
- ui: повторите в o: дерево не работает, как ожидалось
основной причиной вашей проблемы является то, что #{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, чтобы избавиться от стиля виджета( границы и тому подобное), но это тривиальные.