【发布时间】:2012-02-08 21:29:41
【问题描述】:
我是 Stack Overflow 的新手,并且对 JSF 2.0 和自定义组件有疑问(我也使用 primefaces 3,但我认为这并不重要)。情况如下:我有一个AdvancedCriterion 类型的嵌套数据对象,其中包含AdvancedCriterion 或Criterion 的列表(通过接口criteria)。这些标准用于创建一个复杂的过滤器对象,如下所示:
- 高级标准:和
- 标准:PRODUCT 等于“ABC”
- 标准:USER 以“A”开头
- 高级标准:或
- 标准:param1 > 5
- 标准:param2
我在 Java 中创建了两个新组件:AdvancedCriterion.java 和 SimpleCriterion.java 来执行递归,因为第一次尝试使用组合进行递归失败。并且在组合中递归调用组合会导致堆栈溢出:-(
直到知道我可以显示一个静态过滤器对象并且它看起来不错,但用户应该添加或删除标准。所以我添加了一些按钮(这里有primefaces)。这里有一些代码,我从第一个标准开始,始终是AdvancedCriterion。
<myTag:advancedCriteriaComponent criteria="#{manageFiltersBean.filterBuilder.criteria}" />
我创建知道 Button 并希望将父对象提供给 ActionListener:
CommandButton addButton = new CommandButton();
addButton.setId("btnAdd" + UUID.randomUUID());
addButton.setAjax(true);
addButton.setValue(" + ");
addButton.addActionListener(new CriteriaActionListener());
addButton.getAttributes().put("criteria", this.currentCriteria);
好吧,CriteriaActionListener 来了:
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
AdvancedCriteria criteria = (AdvancedCriteria) event.getComponent().getAttributes().get("criteria");
criteria.addCriteria(new Criterion());
System.out.println("number of children: " + criteria.getChildren().size());
}
在组件中,currentCriteria 是众所周知的,我可以看到他的子元素。在CriteriaActionListener 中,对象是空的(它具有正确的类型,但看起来像这种类型的新初始化对象) 现在的问题:我怎样才能将currentCriteria 对象放入CriteriaActionListener?
我在 ActionListener 中尝试了一个属性并从组件中设置它,然后整个对象为 NULL。我虽然尝试制作一个 ELExpression 并将其直接用于 bean (#{manageFiltersBean.addCriterion(criteria}) 但对象为 NULL。我没有更多的想法,不幸的是我对 JSF 很陌生(大约几周)。
也许是关于按钮的 id?它们是随机的,因为按钮的数量是动态的。我读到,每个按钮都必须有一个唯一的 ID 才能正常工作。还是与属性/参数有关?
感谢您的帮助,
菲利克斯
【问题讨论】:
-
欢迎来到 StackOverflow 并感谢您提出了一个措辞精美的问题。您的项目是在客户端还是在服务器上配置为
VIEW_STATE?我问的原因是您的criteria对象可能会被序列化,并且可能由于该对象中的循环引用而不正确(例如,条件 -> childCriteria -> parentCriteria -> childCriteria 等)。尝试删除循环引用,然后查看您的属性是否在 ActionEvent 中传递。 -
... 哦,这个 CommandButton 创建代码发生在哪里?构造函数?渲染阶段?实现BalusC Debug Phase Listener 以更详细地记录每个 JSF 生命周期阶段。
-
感谢您的回复,@maple_shaft。我将尝试回答您的问题:1)
CommandButton是在 encodeBegin() 方法中创建的,这应该是渲染阶段。 2)对象实现可串行化,但这虽然是一个想法。我将尝试使用最简单的数据对象并稍后回复... -
渲染阶段发生在 动作(事件)阶段之后,您在该阶段中查找属性的事件。可能是 Criterion 对象被设置为按钮的属性之后事件发生。这可能是另一个问题。
-
我发现了问题:ActionListener 是对的,也许缺少的“implements Serialiable”也导致了问题。但主要原因是,有人将孩子的列表命名为“criteriaList”,并将这个“getChildren”的getter命名为“getCriteriaList”。
标签: java jsf recursion custom-component