Управляемый компонент как параметр Facelet позволяет составному компоненту предотвращать разрешение
В данном случае я хочу использовать фасет с различными ManagedBeans, поэтому в качестве параметра указывается относящийся к действию bean-компонент:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" >
<h:body>
<ui:include src="ratings.xhtml" >
<ui:param name="createAction" value="#{myOneCreateAction}" />
<ui:param name="ratings" value="#{context.ratings}" />
</ui:include>
</h:body>
</html>
Я даю создать действие в качестве параметра value="#{myOneCreateAction}"
,
В этом фасете есть компонент, который также используется несколько раз на других страницах, поэтому я пытаюсь реорганизовать его в составной компонент.
<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"
xmlns:io="http://java.sun.com/jsf/composite/inoutComponents">
<ui:composition>
<rich:dataTable id="ratingTblId"
value="#{ratings}"
var="rating">
<rich:column>
<io:removeButton
id="removeButton"
actionMethod="#{createAction.removeRating}"
immediate="true"
render=":#{rich:clientId('ratingTblId')}" />
<h:commandButton
id="removeButton2"
actionListener="#{createAction.removeRating}"
immediate="true" >
<f:ajax render="ratingTblId" />
</h:commandButton>
</rich:column>
</rich:dataTable>
</ui:composition>
</html>
Видите, как метод дается как actionMethod="#{createAction.removeRating}"
к компоненту. Сам этот компонент выглядит следующим образом:
<ui:composition 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"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute
name="actionMethod"
targets="remove"
method-signature="void f(javax.faces.event.ActionEvent)"/>
<cc:attribute name="render" required="false" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<h:commandButton
id="remove"
actionListener="#{cc.attrs.actionMethod}"
onclick="if (!confirm('Do you really?')) { return false; }">
<f:ajax execute="@this" render="#{cc.attrs.render}" />
</h:commandButton>
</cc:implementation>
</ui:composition>
и, наконец, что не менее важно, управляемый боб
Name("myOneCreateAction")
@Scope(ScopeType.CONVERSATION)
public class MyOneCreateAction {
...
public void removeRating(ActionEvent ev) {
// do something
}
...
}
Удивительно, но в то время как removeButton2 правильно переходит в правильную функцию, версия составных компонентов возвращает
javax.faces.event.AbortProcessingException: Target Unreachable,
identifier 'createAction' resolved to null
вместо. Использую Mojarra JSF 2.1.26 со швом 2.3.1.CR1. Нет вложенных составных компонентов. При замене составного параметра компонента на #{myOneCreateAction.removeRating}
работает как ожидалось.
Кто-нибудь видел это раньше? Я слепой? Любые обходные пути известны...? Заранее спасибо!
1 ответ
В качестве обходного пути я переписал компонент, чтобы дать бин действия и метод действия как два отдельных параметра, разрешая их следующим образом
XHTML:
<io:removeButton
id="removeButton"
actionBean="#{createAction}"
actionMethod="removeRating"
immediate="true"
render=":#{rich:clientId('ratingTblId')}" />
составной компонент:
<ui:composition 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"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="actionBean" />
<cc:attribute name="actionMethod" />
<cc:attribute name="render" required="false" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<h:commandButton
id="remove"
action="#{cc.attrs.actionBean[cc.attrs.actionMethod]}"
onclick="if (!confirm('Do you really?')) { return false; }">
<f:ajax execute="@this" render="#{cc.attrs.render}" />
</h:commandButton>
</cc:implementation>
</ui:composition>
также изменение сигнатуры методов действия для возврата String
вместо void
, Это уже не выглядит супер секси, но работает.:-/
У меня была такая же проблема, я узнал, что она исправлена в версии 2.2.15:https://github.com/javaserverfaces/mojarra/issues/4271