【问题标题】:Untoggle action resets checkboxes inside a <p:rowExpansion>取消切换操作重置 <p:rowExpansion> 中的复选框
【发布时间】:2016-06-05 06:43:40
【问题描述】:

我在 rowExpansion 中有数据表,我可以通过复选框选择该表的行。我选择其中一些。但是在我单击行切换器图标以取消切换内表后,事件会重置“false”中的复选框。 我可以避免这种行为吗?

汽车品牌:

import java.util.List;

public class CarBrand {

    private final String brandName;
    private final List<CarModel> models;
    private boolean selected;

    public CarBrand(String brandName, List<CarModel> models) {
        this.brandName = brandName;
        this.models = models;
    }

    public String getBrandName() {
        return brandName;
    }

    public List<CarModel> getModels() {
        return models;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

车型:

public class CarModel {

    private final String modelName;
    private final int year;
    private boolean selected;

    public CarModel(String modelName, int year) {
        this.modelName = modelName;
        this.year = year;
    }

    public String getModelName() {
        return modelName;
    }

    public int getYear() {
        return year;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

CDI 托管 Bean:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Named;
import org.primefaces.event.ToggleEvent;
import org.primefaces.model.Visibility;

@Named
@SessionScoped
public class Bean implements Serializable {

    List<CarBrand> brands;

    @PostConstruct
    private void init() {
        brands = new ArrayList<>();
        List<CarModel> carModels;

        carModels = new ArrayList<>();
        carModels.add(new CarModel("CL 63 AMG", 2011, 1));
        carModels.add(new CarModel("S-Class Coupe", 2014, 2));
        carModels.add(new CarModel("AMG GTS", 2015, 3));
        brands.add(new CarBrand("Mercedes", carModels));

        carModels = new ArrayList<>();
        carModels.add(new CarModel("M5 F10", 2012, 4));
        carModels.add(new CarModel("M6 F13", 2012, 5));
        carModels.add(new CarModel("X5 M", 2015, 6));
        brands.add(new CarBrand("BMW", carModels));

        carModels = new ArrayList<>();
        carModels.add(new CarModel("Polo", 2012, 7));
        carModels.add(new CarModel("Golf GTI", 2013, 8));
        carModels.add(new CarModel("Golf R", 2015, 9));
        brands.add(new CarBrand("Volkswagen", carModels));
    }

    public void onRowToggle(AjaxBehaviorEvent event) {
        ToggleEvent toggleEvent = (ToggleEvent) event;
        FacesMessage msg;
        if (toggleEvent.getVisibility() == Visibility.VISIBLE) {
            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Toggled", "Visibility:" + toggleEvent.getVisibility());
        } else {
            msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Untoggled", "Visibility:" + toggleEvent.getVisibility());
        }
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public List<CarBrand> getBrands() {
        return brands;
    }
}

和.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core"
  xmlns:p="http://primefaces.org/ui">
<f:view>
    <h:head>
        <title>TEST</title>
    </h:head>
    <h:body>
        <h:form id="testForm" prependId="true">
            <p:growl id="growl"/>
            <p:dataTable id="carsTable" value="#{bean.brands}" var="brand" style="width: 400px">
                <p:ajax event="rowToggle" listener="#{bean.onRowToggle}" update="testForm:growl"/>
                <p:column style="width: 20px">
                    <p:rowToggler/>
                </p:column>
                <p:column headerText="Brand">
                    <b><h:outputText value="#{brand.brandName}"/></b>
                </p:column>
                <p:rowExpansion>
                    <p:dataTable id="modelsTable" value="#{brand.models}" var="model">
                        <p:column headerText="Model">
                            <h:outputText value="#{model.modelName}"/>
                        </p:column>
                        <p:column headerText="Year">
                            <h:outputText value="#{model.year}"/>
                        </p:column>
                        <p:column style="width: 20px">
                            <f:facet name="header">
                                <p:selectBooleanCheckbox id="selectAll" value="#{brand.selected}" rendered="#{not empty brand.models}">
                                    <p:ajax/>
                                </p:selectBooleanCheckbox>
                            </f:facet>
                            <p:selectBooleanCheckbox id="modelSelect" value="#{model.selected}">
                                <p:ajax/>
                            </p:selectBooleanCheckbox>
                        </p:column>
                    </p:dataTable>
                </p:rowExpansion>
            </p:dataTable>
        </h:form>
    </h:body>
</f:view>

【问题讨论】:

    标签: jsf primefaces


    【解决方案1】:

    问题比你说的还要严重。这是由切换的实现引起的。如果您看到 DOM 中发生了什么,则展开的项目将被完全删除。当您将其切换回时,对象将重新渲染。

    由于某些原因,文本值被保留,但复选框恢复为原始值。

    这种情况是值得的。如果您不展开扩展,则不会提交未呈现的元素,这对于复选框意味着它们的值将更改为“false”,无论它们的原始值是什么。

    你基本上有两种选择:

    1. 将复选框移到扩展之外
    2. 在扩展区域之外使用 Javascript 存储它们的值

    【讨论】:

    • 谢谢,但我已经将它们的值保存在复选框所针对的对象中
    • 我在 Github issue 中看到了一些与此行为相关的活动。我希望PM团队能妥善解决它。上述建议是繁重且不舒服的解决方法。
    猜你喜欢
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 2016-07-18
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多