0

私はこれに行き詰まっています:

    <rich:dataTable id="tabA" value="#{m.a}" rowKeyVar="nr" var="ex">
        <rich:column><h:outputText value="Exercise #{nr + 1}:" /></rich:column>
        <rich:column><h:inputText value="#{ex}" /></rich:column>
    </rich:dataTable>
    <h:panelGrid columns="2">
        <a4j:commandButton value="+" title="new" ajaxSingle="true"
            action="#{m.createNewExercise}" reRender="tabA"/>
        <a4j:commandButton value="-" title="remove last" ajaxSingle="true"
            action="#{m.deleteExercise}" reRender="tabA"/>
    </h:panelGrid>

これはより大きなフォームの一部であるため、 を設定しajaxSingle="true"ました。

私が反復している値は、次のように定義された文字列のリストです。

@Entity
public class M {
    ...
    private List<String> a = Lists.newArrayList();

    @CollectionOfElements
    public List<String> getA() { return a; }
    public void setA(List<String> a) { this.a = a; }
}

これは、送信時にバッキング リストの更新に失敗しますa(送信は単純な 経由で行われ<h:commandButton>ます)。inputText要素のコンテンツが送信されるため、JSF は値の適用に失敗しているようです。これが の@CollectionOfElementsストレージ タイプによるものかどうかを明らかにできる人がいるかもしれませんM

したがって、私が探しているのは、またはexを呼び出すときに値を保存する方法です。完全なテーブルを再レンダリングする必要がないか、最初にサーバーに送信する必要があります。createNewExercisedeleteExercise

おそらくここで提案されているようなバインディングを介して機能させることができますが、バインディングのオーバーヘッドを回避する方法に興味があります。

4

2 に答える 2

0

@KeepAlive簡単な方法: M Bean に注釈を追加します。これにより、同じビューにあるすべてのリクエストに対して Bean が保存および復元されます。セッションでの Bean データの保存と (ほぼ) すべてのリクエストでの復元について心配する必要はありません。

より難しい方法: セッションでリスト値を保存し、M Bean で要求が行われるたびにそれを回復する必要があります。

推奨事項: 可能であれば、JSF 2 および RF 4 に移行してください。JSF 2 には、この種の問題 (およびそれ以上) を解決する ViewScope が既に存在します。

于 2012-07-10T14:06:49.353 に答える
0

問題はajaxSingle="true"属性であり、JSF が明らかに更新できないことが組み合わさっています@CollectionOfElements

の説明でajaxSingleは、そのコンポーネントに属さないすべてのモデルの更新をスキップすることが明確に述べられています (これはdataTable でも value 属性でもありません)。つまり、これは古典的な PEBKAC です。

しかし、これはまだajaxSingleなしでは機能しないため、そのオプションをテストしていたときにJSF側は問題ないと思いました。

私が最終的に得たのは:

<rich:dataTable id="tabA" value="#{m.a}" rowKeyVar="nr" var="ex">
    <rich:column><h:outputText value="Exercise #{nr + 1}:" /></rich:column>
    <rich:column><h:inputText value="#{ex}" /></rich:column>
</rich:dataTable>
<h:panelGrid columns="2">
    <a4j:commandButton value="+" title="new"
        action="#{m.createNewExercise}" reRender="tabA"/>
    <a4j:commandButton value="-" title="remove last"
        action="#{m.deleteExercise}" reRender="tabA"/>
</h:panelGrid>

そして豆:

@Entity
public class M {
  ...
  private List<Exercise> a = Lists.newArrayList();

  @OneToMany(cascade = CascadeType.ALL)
  @JoinColumn(name = "ex_id")
  public List<Exercise> getA() { return a; }
  public void setA(List<Exercise> a) { this.a = a; }
}

@Entity
public class Exercise {
  [id definition omitted]
  private M m;
  private String description;

  @ManyToOne
  @JoinColumn(name = "ex_id", insertable = false, updatable =false)
  public M getM() { return m; }
  public void setM(M m) { this.m = m; }

  public String getDescription() { return description; }
  public void setDescription(String d) { this.description = d; }
}
于 2012-07-12T07:48:14.483 に答える