複数のテキスト入力を可能にする複合コンポーネントを作成しようとします。私は、コンポジットコンポーネントのバッキングコンポーネントを定義することが可能であるので、レンダラーやハンドラを記述する必要はありません。私が理解できなかったことは、複合コンポーネントのxhtmlで宣言されたアクションをバッキングコンポーネントに委譲する方法です。私はまだこれの概念をかなり理解していないと思う。誰にもアイディアがありますか?複合コンポーネントのバッキングコンポーネントのActionListenerを呼び出す
私はクロサギ科2.1.7、Tomcatの7、EL 2.2、春3を使用しています
これは私がコンポーネントを使用したい方法です:
<custom:multiInput value="#{backingBean.inputList}"/>
BackingBean.java
@Component
@Scope(value="view")
public class BackingBean {
...
private List<Foo> inputList;
....
}
multiInput.xhtmlはTHIのように見える複合コンポーネント:は、オブジェクトのリストを保持しています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>
そしてここでバッキングコンポーネント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);
}
...
}
からremoveRow
とaddEmptyRow
が多入力に呼び出されることはありません。 Ajaxリクエストがトリガーされますが、どこかで失われます。どうして?
は、コンポジットやその親に 'rendered'属性がありますか?もしそうなら、フォーム提出中に「真」と評価するのは100%ですか? http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invokedも参照してください。ちょっとした赤い文字列がコード内にあります。簡略化/名前を変更するときは注意してください。 – BalusC
thx @BalusC、私はサンプルを更新しました。はい、私は、すべての親コンポーネントの 'rendered'属性が' true'に評価されていることを確認しました。私が不思議に思うのはポイント4です。[stackoverflow.com/questions/2118656/...](http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoked)バッキングコンポーネントが保持されていないようです。削除または追加ボタン「CompositeComponentTagHandler.createComponent」をクリックするたびに、バッキングコンポーネント 'MultiInput'の新しいインスタンスが作成されます。しかし、なぜ? – fischermatte
私はこれまでのようなコンポーネントを作成しており、うまく動作します。あなたの正確なコードをコピーしました(単純化のために 'Foo'と' MultiSelectRow'を 'Object'で置き換えただけです)、うまく動作します。あなたの具体的な問題は、これまでに投稿されたコードには表示されていません。たぶんネストされたフォーム。 'false'を評価する' rendered'属性かもしれません。知るか。唯一の違いは、私はSpringを使用していないため、Bean上で標準のJSFアノテーションを使用したことです。 – BalusC