1

我在 JSF + JPA 应用程序中有双边的一对多关系。我想从视图中的列表中仅列出过滤的项目。在控制器中进行操作很困难,是否可以像下面这样进行过滤?

<p:selectOneListbox id="cmbField" value="#{investigationItemController.current}" >
     <f:selectItems value="#{investigationItemController.currentInvestigation.reportItems}" var="ri" itemLabel="#{ri.name}" itemValue="#{ri}" itemRendered="#{ri.retired ne true and ri.ixItemType eq 'Value'}" />        
</p:selectOneListbox>

由于 itemRendered 不是属性,我尝试了这个,但失败了。

<p:selectOneListbox id="cmbField" value="#{investigationItemController.current}" >
    <ui:repeat value="#{investigationItemController.currentInvestigation.reportItems}" var="ri" >
        <h:panelGroup rendered="#{ri.retired ne true and ri.ixItemType eq 'Value'}" >
            <f:selectItem itemLabel="#{ri.name}" itemValue="#{ri}" />
        </h:panelGroup>
   </ui:repeat>
</p:selectOneListbox>

所有者实体如下。

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class InvestigationItem extends ReportItem implements Serializable {

    private static final long serialVersionUID = 1L;


    @OneToMany(mappedBy = "investigationItem", cascade= CascadeType.ALL)
    List<InvestigationItemValue> investigationItemValues;

    public List<InvestigationItemValue> getInvestigationItemValues() {
        return investigationItemValues;
    }

    public void setInvestigationItemValues(List<InvestigationItemValue> investigationItemValues) {
        this.investigationItemValues = investigationItemValues;
    }



}

另一个实体如下

@Entity
public class InvestigationItemValue implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    private InvestigationItem investigationItem;
    private String name;

    //Getters and setters and some other fields


}

控制器类的重要代码集如下

@ManagedBean
@SessionScoped
public final class InvestigationItemController implements Serializable {

    private static final long serialVersionUID = 1L;
    @EJB
    private InvestigationItemFacade ejbFacade;
    private InvestigationItem current;
    private Investigation currentInvestigation;

    // Other code goes here

}

在 JSF/Primefaces 中使用 f:selectItem 或 f:selectItems 时如何过滤项目?

(我将解释我的真实情况,为什么我迫切需要这个功能。

我正在开发一个医疗应用程序,术语很混乱。测试或调查(如全血细胞计数或尿液完整报告)可以具有多个属性。测试表示为调查实体。由一个或多个字段组成的测试(如血红蛋白、FBC 的白细胞计数和颜色、UFR 的外观)。它表示为 InvestigationItem。一个单一的 InvestigationItem 可能有一个可能值的列表,在不同的场合选择其中一个。它们被标识为 InvestigationItemValue。所以一个 InvestigationItem 有一个 InvestigationItemValue(s) 列表。但是,例如,一些 InvestigationItemValues 可能是字符串类型,而另一些可能是数字类型。在设计一种特定类型的新调查时,用户需要选择一个 InvestigationItemValue。所以在视图中需要过滤。)

4

1 回答 1

8

PrimeFaces<p:selectOneListbox>实际上隐藏<select><option>并生成了一个<div><ul><li>允许你更多的 CSS 样式自由。

您可以只使用itemDisabled属性,然后使用 CSS 将禁用项目设置为display: none.

<p:selectOneListbox ...>
    <f:selectItems value="#{investigationItemController.currentInvestigation.reportItems}" 
        var="ri" itemLabel="#{ri.name}" itemValue="#{ri}"
        itemDisabled="#{not ri.retired and ri.ixItemType eq 'Value'}" />
</p:selectOneListbox>

有了这个 CSS

.ui-selectlistbox-item.ui-state-disabled {
    display: none;
}

至于你失败的尝试<ui:repeat>;它失败了,因为它<f:selectItem>是在视图构建时评估的,而不是在视图渲染时。但是,<ui:repeat>在视图渲染期间运行。在那一刻,<f:selectItem>组件树中无处可用。它应该在视图构建期间附加到UISelectOne/父级。UISelectMany

JSTL 在视图构建期间运行,例如<f:selectItem>,因此将 JSTL<c:forEach>用于循环和<c:if>条件构建(不是渲染!)也应该这样做:

<p:selectOneListbox ...>
    <c:forEach items="#{investigationItemController.currentInvestigation.reportItems}" var="ri">
        <c:if test="#{not ri.retired and ri.ixItemType eq 'Value'}">
            <f:selectItem itemLabel="#{ri.name}" itemValue="#{ri}" />
        </c:if>
    </c:forEach>
</p:selectOneListbox>

您只需要考虑在使用早于 2.1.18 的 Mojarra 版本时这会破坏视图范围的 bean。

也可以看看:

于 2013-07-13T22:04:47.690 回答