首页 > 解决方案 > JSF 在命令按钮操作后重新加载 ViewParam

问题描述

我正在使用 JSF 和 Primefaces。我有一个带有 af:viewParam 的 edit.xhtml 页面接收实体 ID:

<f:viewParam name="id" value="#{backingBean.entity}" converter="entityConverter" />

我有两个commandButton,一个用来提交和保存实体:

<p:commandButton ajax="false" value="#{bundle.save}" 
action="#{backingBean.save()}"/>

另一个将项目添加到实体集合中:

<p:commandButton ajax="true" process="@this" value="#{bundle.add}" 
actionListener="#{backingBean.addItem()}" />

这是我的 BackingBean:

@ViewScoped 
@Named("backingBean")
public class BackingBean {
  @EJB
  MyDAO myDAO;

  private Entity entity; //with getters and setters

  public void addItem() {
    entity.getData().add(new Item()); //another entity object
  }

  public void save(){
    myDAO.save(entity);
  }
...
}

我还有一个 EntityConverter 类,它调用 DAO 并加载对象:

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    try {
        return myDAO.findById(Entity.class, Long.valueOf(value));
    } catch (Exception e) {
        return null;
    }
}

如果我尝试添加多个项目或单击保存按钮,则会通过调用转换器类的 getAsObject 方法重新加载 BackingBean 类中的实体。

我做错了什么?谢谢!

标签: jsfprimefacesconverter

解决方案


为清楚起见,正常的 f:param 将始终以这种方式运行。我在所有项目中都使用OmniFaces ViewParam来解决这些问题。

无状态模式可避免回发时不必要的转换、验证和模型更新

标准 UIViewParameter 实现在回发后再次调用模型设置器。当绑定到视图范围的 bean 时,这并不总是需要的,并且在与昂贵的转换器结合使用时可能会导致性能问题。为了解决这个问题,这个组件默认将提交的值存储为组件属性而不是模型中(因此在绑定到视图范围 bean 的情况下在视图状态中)。

标准 UIViewParameter 实现在回发时再次调用转换器和验证器。当您有一个 required="true" 时,这并不总是需要的,但该参数不会保留在表单提交上。您需要在每个命令链接/按钮上保留它。为了解决这个问题,这个组件不会在回发时再次调用转换器和验证器。


推荐阅读