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在调用createNewExerciseor时保存值的方法deleteExercise,要么不必重新渲染完整的表,要么先将它们发送到服务器。

我可能可以通过此处建议的绑定使其工作,但我对避免绑定开销的方法感兴趣。

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 回答