versuchen Sie, eine zusammengesetzte Komponente zu schreiben, die mehrere Texteingaben zulässt. Ich habe gelesen, dass es möglich ist, eine Backing-Komponente für eine Composite-Komponente zu definieren, so dass ich weder einen Renderer noch einen Handler schreiben muss. Was ich nicht herausfinden konnte, ist, wie Aktionen, die in der xhtml-Datei von composite deklariert sind, an die unterstützende Komponente delegiert werden. Ich glaube, ich habe das Konzept noch nicht verstanden. Hat jemand eine Idee?Aufrufen des ActionListener der Backing-Komponente in der Composite-Komponente
Ich benutze Tomcat 7, EL 2.2, Frühling 3, Mojarra 2.1.7
Dies ist der Weg Ich mag würde die Komponente verwenden:
<custom:multiInput value="#{backingBean.inputList}"/>
Wo die BackingBean.java hält eine Liste von Objekten:
@Component
@Scope(value="view")
public class BackingBean {
...
private List<Foo> inputList;
....
}
Verbundbauteil multiInput.xhtml wie thi aussieht s:
<cc:interface componentType="MultiInput">
<cc:attribute name="value" required="true" type="java.util.List" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:dataTable value="#{cc.attrs.rows}" var="row">
<h:column>
<!-- here will be a selector component in order to select a foo object -->
</h:column>
<h:column>
<h:commandButton value="Remove Row">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.removeRow(row)}" />
</h:commandButton>
</h:column>
<h:column>
<h:commandButton value="Add Row" rendered="#{cc.lastRow}">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.addEmptyRow()}" />
</h:commandButton>
</h:column>
</h:dataTable>
</div>
</cc:implementation>
Und hier die Trägerkomponente MultiInput.java:
@FacesComponent(value="MultiInput")
public class MultiInput extends UIInput implements NamingContainer, Serializable{
...
@Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
initRowsFromValueAttribute();
super.encodeBegin(context);
}
public void removeRow(MultiInputRow row) {
// why is this method is never reached when clicking remove button?
}
public void addEmptyRow() {
// why is this method is never reached when clicking add button?
}
public ListDataModel<MultiSelectRow> getRows() {
return (ListDataModel<MultiSelectRow>) getStateHelper().eval(PropertyKeys.rows, null);
}
private void setRows(ListDataModel<MultiSelectRow> rows) {
getStateHelper().put(PropertyKeys.rows, rows);
}
...
}
jetzt - removeRow
und addEmptyRow
wird nie auf Multiinput genannt. Eine Ajax-Anfrage wird ausgelöst, aber sie geht irgendwo verloren. Warum?
Gibt es ein 'rendered' Attribut auf dem Verbund oder eine ihrer Eltern? Wenn ja, sind Sie zu 100% der Meinung, dass "wahr" während der Übermittlung des Formulars ausgewertet wird? Siehe auch http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoiced Sie haben übrigens ziemlich viele rote Heringe im Code. Bitte seien Sie vorsichtig beim Vereinfachen/Umbenennen. – BalusC
thx @BalusC, ich habe das Sample aktualisiert, so dass es weniger "rote Heringe" (hoffentlich) hat. Ja, ich habe überprüft, dass alle gerenderten Attribute der Elternkomponente zu "wahr" ausgewertet werden. aber was mich wundern lässt, ist Punkt 4 in [stackoverflow.com/questions/2118656/...](http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoked). Es scheint, dass die Hintergrundkomponente nicht erhalten bleibt. Jedes Mal, wenn ich auf die Schaltfläche zum Entfernen oder Hinzufügen klicke, wird 'CompositeComponentTagHandler.createComponent' eine neue Instanz der Backing-Komponente' MultiInput' erzeugen. aber warum? – fischermatte
Ich habe solche Komponenten schon einmal erstellt und sie funktionieren gut. Ich kopierte den genauen Code (ich habe 'Foo' und' MultiSelectRow' nur durch 'Object' ersetzt) und es funktioniert gut. Ihr konkretes Problem wird an anderer Stelle verursacht, was in dem bisher veröffentlichten Code nicht gezeigt wird. Vielleicht eine verschachtelte Form. Vielleicht ein "gerendertes" Attribut, das "falsch" auswertet. Wer weiß. Der einzige Unterschied ist, dass ich Spring nicht verwende und daher nur Standard-JSF-Annotationen für die Bean verwende. – BalusC