【问题标题】:How to use SelectManyCheckbox with two ArrayList? - Primefaces如何将 SelectManyCheckbox 与两个 ArrayList 一起使用? - Primefaces
【发布时间】:2013-11-21 22:07:20
【问题描述】:

我正在尝试实现<p:selectManyCheckbox>,但没有成功。

现在我有以下架构:

Course - have many Disciplines
Discipline - belongs to none, one or many Courses.

Course 班级我有两个ArrayList<Discipline>

public class CourseMBean{

    (...)
    // Stores all disciplines
    private static ArrayList<Discipline> allDisciplines;

    // Stores only the disciplines that's already associated with this course.
    private static ArrayList<Discipline> courseDisciplines;

    (get and set for the arraylists)
    (...)
}

所有数据都来自 MYSQL DB,但这不是问题所在。现在我想创建一个新课程,所以我在 courseDisciplines 中没有任何内容。

我想在复选框中显示所有学科,并希望当用户选择一个复选框时,将此复选框的对象学科添加到 courseDisciplines 中 - 当取消选择一个复选框时,从 courseDsiciplines 中删除学科。

我的 JSF 2.0 代码如下:

<p:selectManyCheckbox id="disciplines" value="#{courseMBean.allDisciplines}" layout="grid" columns="2">                                          
     <f:selectItems value="#{courseMBean.courseDisciplines}" />
</p:selectManyCheckbox>

这实际上显示了所有学科,没有任何选中的复选框,这是正确的。但是当我选择一些复选框并提交表单时,我尝试在 courseDisciplines 中打印元素,这不会在控制台中显示任何内容。

我做错了什么?

【问题讨论】:

  • selectManyCheckbox 是否包含在表单中? CourseMBean 的范围是什么?
  • 是的,他在一个表单中,范围是@SessionScoped。有什么问题吗,这应该可以按我的意愿工作吗?
  • 我很难理解您的问题。为什么您尝试打印可用项目而不是所选项目,为什么可用项目显然是空的,但您显然可以在 UI 中选择它们?

标签: jsf primefaces selectmanycheckbox


【解决方案1】:

当我选择一些复选框并提交表单时,我尝试打印 courseDisciplines 中的元素

由于courseDisciplines 实际上代表可用 项而不是选定 项,您似乎误解了UISelectManyUISelectItem(s) 组件的一些基本概念.

&lt;f:selectItem(s)&gt;(来自UISelectItem(s) 系列)代表可用 项。正是这些项目显示在 UI 中并且最终用户必须从中进行选择。

&lt;p:selectManyCheckbox&gt;value 属性(来自UISelectMany 系列,如&lt;h:selectManyCheckbox&gt;&lt;h:selectManyMenu&gt;)表示(预)选择 项。如果在第一次显示表单期间它为 null 或为空,则不会预先选择任何内容。或者,如果其中包含一些预选项目,则只有equal() 的可用项目将被预选。

当最终用户更改 UI 中的选择并提交表单时,所有选定的项目将最终出现在 UISelectMany 组件的 value 属性中。 UISelectItem(s) 保持不变。

这是一个基本的启动示例:

<p:selectManyCheckbox value="#{bean.selectedItems}">
    <f:selectItems value="#{bean.availableItems}" />
</p:selectManyCheckbox>
<p:commandButton value="Submit" action="#{bean.submit}" />
<p:messages autoUpdate="true" />
private List<String> selectedItems; // +getter +setter
private List<String> availableItems; // +getter (no setter necessary!)

@PostConstruct
public void init() {
    availableItems = new ArrayList<String>();
    availableItems.add("one");
    availableItems.add("two");
    availableItems.add("three");
}

public void submit() {
    System.out.println("Selected items: " + selectedItems);
}

(所有其他 &lt;p:selectManyXxx&gt;&lt;h:selectManyXxx&gt; 组件的工作方式完全相同)

当像Discipline 这样的复杂Javabean 对象出现时,您需要确保有一个Converter,以便JSF 可以在它和String 之间正确转换以用于生成的HTML 输出和作为 HTTP 请求参数(HTML 和 HTTP 即不能传递也不能保存 Java 对象,只能传递 Java 中由String 表示的字符序列)。

这可能是您的根本问题。您说提交时没有任何内容打印到控制台。但是,整个submit() 方法实际上从未被调用的情况也可能是一样好。你在这方面不够明确。如果整个操作方法确实从未被调用(即调试断点没有命中,或者另一个System.out.println() 打印静态字符串从未在控制台中显示),那么您实际上很可能是转换错误。如果您以正确的方式使用&lt;h|p:message(s)&gt;,或者关注服务器日志中关于排队但未显示的人脸消息,那么您应该已经注意到了。

在这种情况下,您需要实现一个Converter,它在DisciplineString 之间进行转换。

@FacesConverter(forClass=Discipline.class)
public class DisciplineConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        // Write code here to convert from String to Discipline.
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        // Write code here to convert from Discipline to String.
    }

}

DB ID 经常被用作String 表示。另请参阅此答案的“作为选定项目的复杂对象”部分,了解相关问题:How to populate options of h:selectOneMenu from database?

【讨论】:

  • 再次感谢 Balusc!只是一个小问题:在转换器中,我可以得到 Discipline “id” 值而不是 Discipline “name”吗?我这样说是因为句柄字符串不像 ints (id) 那样安全和快速,从 DB 中获取带有 ID 而不是“名称”的值更安全,对吧?
  • 我使用了 Omnifaces,来自您在 stackoverflow.com/questions/6848970/… 的另一个答案,再次感谢!
猜你喜欢
  • 2013-12-23
  • 2014-11-14
  • 2013-11-28
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多