4

我正在尝试实施,<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 中打印元素,这不会在控制台中显示任何内容。

我做错了什么?

4

1 回答 1

9

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

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

<f:selectItem(s)>来自UISelectItem(s)家庭)代表可用的项目。正是这些项目显示在 UI 中并且最终用户必须从中进行选择。

(来自家庭,like和)的value属性表示(预)选择的项目。如果在第一次显示表单期间它为 null 或为空,则不会预先选择任何内容。或者如果这包含一些预选的项目,那么只有那些可用的项目将被预选。<p:selectManyCheckbox>UISelectMany<h:selectManyCheckbox><h:selectManyMenu>equal()

当最终用户更改了 UI 中的选择并提交了表单时,所有选择的项目都将最终出现在组件的value属性中UISelectManyUISelectItem(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);
}

(所有其他<p:selectManyXxx><h:selectManyXxx>组件的工作方式完全相同)

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

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

在这种情况下,您需要实现在和Converter之间转换的 a 。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表示。另请参阅此答案的“作为选定项目的复杂对象”部分,了解相关问题:如何从数据库中填充 h:selectOneMenu 的选项?

于 2013-11-11T11:53:37.920 回答