JSF AJAX调用在支持BEAN中未正确更新动态列表



我有以下问题。我有一个由动态生成的复选框组成的列表。当我单击其中一个复选框时,此调用的背bean值可以。单击另一个复选框时,该复选框很好,但是其他复选框却落回了错误,甚至在前端显示了复选框。同样的问题,当我单击最终提交按钮时。背bean中的所有值成为状态 false

这是JSF:

<?xml version="1.0"?>
<f:view
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head />
    <h:body>
        <h:form>
            <h:messages/>
            <h:dataTable value="#{registration.registrationlist}" var="entry">
                <h:column>
                    <f:facet name="header">Name</f:facet>
                    #{entry.me.name}
                </h:column>
                <h:column>
                    <f:facet name="header">Status</f:facet>
                    <h:selectBooleanCheckbox value="#{entry.checked}">
                    </h:selectBooleanCheckbox>
                </h:column>
            </h:dataTable>
            <h:commandButton value="Submit">
                <f:ajax listener="#{registration.listener}" />
            </h:commandButton>
        </h:form>
    </h:body>
</f:view>

这是我的背豆:

package de.rwd.mm.beans;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;
@ManagedBean
@ViewScoped
public class Registration {
    private List<RegistrationEntry> registrationlist; 
    public Registration() {
        // Populating the registrationlist from database and initialize it with false
        List<MarketingEvent> me_list;
        me_list = MarketingEventLocalServiceUtil.getAllMarketingevents();
        registrationlist = new ArrayList<RegistrationEntry>();
        for (MarketingEvent me : me_list) {
            RegistrationEntry re = new RegistrationEntry(me, false);
            registrationlist.add(re);
        }
    }
    public List<RegistrationEntry> getRegistrationlist() {
        return registrationlist;
    }
    public void setRegistrationlist(List<RegistrationEntry> registrationlist) {
        this.registrationlist = registrationlist;
    }
    public void listener(AjaxBehaviorEvent event) {
        System.out.println("listener");
        System.out.println("called by " + event.getComponent().getClass().getName());
        for (RegistrationEntry entry : registrationlist) {
            String me = entry.getMe().getName();
            boolean value = entry.isChecked();
            System.out.println(me + " " + value);
        }
    }
}

我的登记课程中保存数据库值和复选框的布尔值。

package de.rwd.mm.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import de.rwd.mm.services.model.MarketingEvent;
@ManagedBean
@ViewScoped
public class RegistrationEntry {
    private MarketingEvent me;
    private boolean checked;
    public RegistrationEntry() {
    }
    public RegistrationEntry(MarketingEvent me, boolean checked) {
        this.me = me;
        this.checked = checked;
    }
    public MarketingEvent getMe() {
        return me;
    }
    public void setMe(MarketingEvent me) {
        this.me = me;
    }
    public boolean isChecked() {
        return checked;
    }
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
}

@ViewScop是正确的范围吗?还是有什么完全错误的?

非AJAX版本有效,但这对我来说是没有选择。这个" portlet"放置在几页中,其中包含很多内容,并且页面刷新看起来非常丑陋。此JSF在Liferay 6.2中以Portlet的形式运行。

感谢您的任何帮助和建议。

ps:我的liferay 6.2.0-ce-ga1在tomcat 7.0.42

中运行

使用<f:ajax execute="@form">设置,就像此示例代码一样(它使用Lombok @Data注释来避免键入Getter/Setter方法(:

样品刻面:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head>
    <title>Facelet Title</title>
  </h:head>
  <h:body>
    <h:form>
      <h:dataTable value="#{myBean.records}" var="record">
        <h:column>
          <f:facet name="header">Name</f:facet>
          #{record.name}
        </h:column>
        <h:column>
          <f:facet name="header">Selected</f:facet>
          <h:selectBooleanCheckbox value="#{record.checked}"/>
        </h:column>
      </h:dataTable>
      <h:commandButton value="Submit">
        <f:ajax listener="#{myBean.onSubmit}" execute="@form"/>
      </h:commandButton>
    </h:form>
  </h:body>
</html>

托管bean:

package x;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import lombok.Data;
@Data
@Named( value = "myBean" )
@ViewScoped
public class MyBean implements Serializable
{
  private List<MyRecord> records;
  //@EJB
  //private RecordDAO recordDAO;
  @PostConstruct
  public void init()
  {
    System.out.println( "MyBean.ini() called");
    records = new ArrayList<>();
    records.add( new MyRecord( "Name 1", false ) );
    records.add( new MyRecord( "Name 2", false ) );
    records.add( new MyRecord( "Name 3", false ) );
    records.add( new MyRecord( "Name 4", false ) );
    records.add( new MyRecord( "Name 5", false ) );
  }
  public void onSubmit( AjaxBehaviorEvent abe_ )
  {
    System.out.println( "MyBeam.onSubmit() called! Values : " + getRecordValues() );
    // You should take care about persisting data here
    //recordDAO.persistRecords( records );
  }
  protected String getRecordValues()
  {
    String s = "";
    for ( MyRecord mr : records)
      s += "( name=" + mr.getName() + ", checked= " + mr.isChecked() + " ); ";
    return s;
  }
  public MyBean()
  {
  }
}

测试数据库记录:

package x;
import java.io.Serializable;
import lombok.Data;
@Data
public class MyRecord implements Serializable
{
  private String name;
  private boolean checked;
  public MyRecord( String name_, boolean checked_ )
  {
    name = name_;
    checked = checked_;
  }
}

最新更新