【问题标题】:Primefaces picklist. Setter for DualListModel removes source and targetPrimefaces 选项列表。 DualListModel 的设置器删除源和目标
【发布时间】:2012-05-28 20:12:39
【问题描述】:

我的选择列表有问题。显示源和目标有效,但是当按下命令按钮时,它会调用选择列表的设置器并清空选择列表的源和目标。之后它调用方法connectTags()。

这种行为的原因是什么,我该如何解决?

<h:form>
    <p:pickList id="pickList" value="#{employeeEditController.dualListTags}"
        var="tag" itemLabel="#{tag.value}" itemValue="#{tag}">
        <f:facet name="sourceCaption">Available</f:facet>
        <f:facet name="targetCaption">Connected</f:facet>  
    </p:pickList>
    <p:commandButton value="Save" actionListener="#{employeeEditController.connectTag()}"/>
</h:form>

豆子:

@Named(value = "employeeEditController")
@SessionScoped
public class EmployeeEditController implements Serializable, IEditController {
    private Employee selectedEmployee;
    private DualListModel<Tags> dualListTags;

@Inject
private EmployeeFacade employeeFacade;
@Inject
private CompanyFacade companyFacade;
@Inject
private TagFacade tagFacade;

public void setSelectedEmployee(Employee selectedEmployee) {
    System.out.println("setSelectedEmployee called. Value: " + selectedEmployee.getFirstName());
    this.selectedEmployee = selectedEmployee;
    this.refreshDualList();
}

private void refreshDualList(){
    List<Tags> source = (List<Tags>) this.getCompanyTags();
    List<Tags> target = (List<Tags>) this.getTags();
    System.out.println("refreshDualList called. \nSource: " + source.size() +
            "Target: " + target.size());
    this.dualListTags = new DualListModel<Tags>(source, target);
}

public Collection<Tags> getTags(){
    Collection<Tags> retVal;
    if(this.selectedEmployee != null){
        retVal = this.selectedEmployee.getTags();
        if(retVal == null){
           retVal = new ArrayList<Tags>();
        } 
    } else{
        System.out.println("selected emp is null");
        retVal = new ArrayList<Tags>();
    }
    return retVal;
}

public Collection<Tags> getCompanyTags() {
    Collection<Tags> retVal = new ArrayList<Tags>();
    if(this.companyID == null){
        String userstr = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
        this.companyID = this.companyFacade.getCompanyIDByUser(userstr);
    }
    retVal = this.tagFacade.getTagsFromCompanyID(companyID);
    return retVal;
}

public void save(){
    if(this.selectedEmployee != null){
        System.out.println("Save called. Value: " + this.selectedEmployee.getFirstName());
        this.employeeFacade.edit(this.selectedEmployee);
    }
}

public void connectTag() {
    if(this.dualListTags != null){
        System.out.println("connectTag() called.\n" + "source: " + this.dualListTags.getSource().size() + 
                "\ntarget: " + this.dualListTags.getTarget().size());
        this.selectedEmployee.setTags((Collection<Tags>)this.dualListTags.getTarget());
        this.save();
    }
}

public DualListModel<Tags> getDualListTags() {
    System.out.println("getDualList called. \nSource :" + this.dualListTags.getSource().size()
            + "\nTargets: " + this.dualListTags.getTarget().size());
    return this.dualListTags; 
}

public void setDualListTags(DualListModel<Tags> dualListTags) {
    System.out.println("setDualList called. \nSource :" + this.dualListTags.getSource().size()
            + "\nTargets: " + this.dualListTags.getTarget().size());
    this.dualListTags = dualListTags;
    System.out.println("setDualList called after set. \nSource :" + this.dualListTags.getSource().size()
                + "\nTargets: " + this.dualListTags.getTarget().size());
    }

}

【问题讨论】:

  • 展示示例对您有用吗? primefaces.org/showcase/ui/picklist.jsf 一步一步地构建,直到它以同样的方式失败并且你找到了原因。
  • connectTags 方法从保存在控制器中的对偶列表中获取源和目标。但是 setter 被调用并清空了对偶列表
  • connectTags() 返回什么 - 是返回 JavaScript 以在浏览器中运行吗?
  • 如果你真的想解决这个问题,发sscce
  • 如果您根据此处的 cmets 修改了代码,则必须将更改应用到您的帖子中,否则会产生误导或不相关。此外,一个好主意是清理您的代码,以便出现有问题的区域。如果您不确定其他代码(您应该在此处省略的代码)是否会导致问题,那么请在提交问题之前制作一个示例并对其进行测试。

标签: jsf primefaces


【解决方案1】:

我遇到了同样的问题,似乎解决方案是为您在选择列表中使用的实体实施自定义转换器。

这是我的自定义转换器的样子:

@ViewScoped
@ManagedBean(name = "vehicleGroupConverter")
public class VehicleGroupConverter implements Converter {

    @ManagedProperty(value = "#{vehiclesBean}")
    private VehiclesBean vehiclesBean;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        long groupId = Long.parseLong(value);
        List<AssetCategory> groups = vehiclesBean.getVehicleGroups();
        for (AssetCategory group : groups) {
            if (group.getCategoryId() == groupId) {
                return group;
            }
        }
        return null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        return Long.toString(((AssetCategory) value).getCategoryId());
    }

    public void setVehiclesBean(VehiclesBean vehiclesBean) {
        this.vehiclesBean = vehiclesBean;
    }

}

这是选择列表模板部分:

<p:pickList id="vehicleGroups" 
        value="#{vehiclesBean.selectedVehicleGroups}" 
        var="group" 
        itemLabel="#{group.name}" 
        itemValue="#{group}"
        converter="#{vehicleGroupConverter}"
        styleClass="pf-panel-grid"
        style="margin-bottom:10px">
    <f:facet name="sourceCaption">#{i18n['label-available-groups']}</f:facet>
    <f:facet name="targetCaption">#{i18n['label-assigned-groups']}</f:facet>
</p:pickList>

【讨论】:

  • 为什么ConverterManagedBean
  • 一般来说没有理由这样做。这在我正在开发的特定应用程序中非常方便。
【解决方案2】:

当源或目标不为空时设置duallistmodel:

public void setDualListTags(DualListModel<Tags> dualListTags) {
    if(this.dualListTags.getSource().size()!=0 && this.dualListTags.getTarget().size()!=0) {
        this.dualListTags = dualListTags;
    }
}

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多