2

文字列のリストと、リストに文字列を追加するためのいくつかのコントロールを表示するだけのui:repeaterタグが付いたJSFページがあります。文字列を追加するときは、ajaxを使用してリピータータグを更新し、ページを更新せずに新しい文字列をすぐに表示します。私のページは次のようになります。

<h:body>
    <h:form>
        <p:inputText id="name" value="#{testController.newString}"/>
        <p:commandButton value="Add" actionListener="#{testController.addString}" update="strings" />
    </h:form>       

    <h:panelGroup id="strings">         
        <ui:repeat var="str" value="#{stringModel.strings}" varStatus="stringData">                                                                                                             
            <div>                                       
                <h:outputText value="#{str}" />
                <h:inputText value="#{str}" />
            </div>                                                                                  
        </ui:repeat>
    </h:panelGroup>                              

</h:body>

inputTextコンポーネントを除いてすべてが機能します。ui-repeaterがAjaxで更新された後も、前の文字列のテキストが表示されます。たとえば、最初に「val1」と「val2」の2つの文字列を持つリストがあるとします。「val3」という新しい文字列を入力して、フォームを送信します。リストはサーバー側で正しく更新され、リピーターが更新され、3つの要素が含まれるようになりました。ただし、新しく追加された要素のh:outputTextには「val3」が正しく表示されますが、inputTextには「val2」が値として表示されます。だから私はこのように見えるものになってしまいます:

output tag     input tag
val1           val1
val2           val2
val3           val2 (???)

バッキングBeanは非常に単純です。ビュースコープのモデルBean

@Component
@Scope("view")
public class StringModel {

    private List<String> strings = Lists.newArrayList("Value 1");

    public List<String> getStrings() {
        return strings;
    }

    public void setStrings(List<String> strings) {
        this.strings = strings;
    }   
}

そして、リクエストスコープのコントローラーBean:

@Component
@Scope("request")
public class TestController {

    private String newString;
    @Autowired private StringModel model;

    public void addString() {
        model.getStrings().add(newString);
    }

    public String getNewString() {
        return newString;
    }

    public void setNewString(String newString) {
        this.newString = newString;
    }   

}

私はいくつかのテストを行いましたが、これは実際には、textInput、textAreaなどのどの入力コンポーネントでも同じように機能します。助けていただければ幸いです。

4

3 に答える 3

6

更新後に間違った値が表示される理由を正確に知ることはできませんが(の内部ループインデックス<ui:repeat>が壊れている可能性があります。新しいバージョンのMojarraを試してください)、文字列アイテムをインデックスで参照しているだけvarStatusです。Stringまた、クラスは不変であり、セッターがないため、このリストをフォームに入力すると、編集された文字列値を送信できないという将来の問題もすぐに修正されます。

<ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
    <div>
        <h:outputText value="#{str}" />
        <h:inputText value="#{stringModel.strings[loop.index]}" />
    </div>
</ui:repeat>
于 2011-08-13T17:19:48.960 に答える
2

ui:repeat内のEditableValueHoldersは、現在のバージョンのJSF仕様では(設計上)壊れています。それは動作しません、それを修正する方法はありません。たぶん、新しいバージョンは、その子の状態を保存するためのサポートを備えた適切なコンポーネントをui:repeatにするでしょう。そうでないかもしれない。

ui:repeatをh:dataTableに変更すると、動作するはずです(そうでない場合は、問題は別の場所にあり、私は間違っていました)。

率直に言って、他のいくつかのライブラリのリピーターを使用する以外に回避策はありません。トマホーク、トリニダード、および他の多くの場所で機能するリピーターを見つける必要があります。Primefaces、AFAIRには、純粋なリピーターはありません。

于 2011-08-13T17:12:14.753 に答える
0

以前もまったく同じ問題がありました。inputTextをフォームに入れることで解決しました。私もあなたのコードをコピーして、h:inputText中に入れました、h:formそしてそれは同様に働きました。

<h:form>
    <ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
        <div>
            <h:outputText value="#{str}" />
            <h:inputText value="#{str}" />
        </div>
    </ui:repeat>
</h:form>
于 2013-02-03T09:31:59.100 に答える