【问题标题】:JSF 2: Create a custom component with CommandButton and get attribute to ActionListenerJSF 2:使用 CommandButton 创建自定义组件并获取 ActionListener 的属性
【发布时间】:2012-02-08 21:29:41
【问题描述】:

我是 Stack Overflow 的新手,并且对 JSF 2.0 和自定义组件有疑问(我也使用 primefaces 3,但我认为这并不重要)。情况如下:我有一个AdvancedCriterion 类型的嵌套数据对象,其中包含AdvancedCriterionCriterion 的列表(通过接口criteria)。这些标准用于创建一个复杂的过滤器对象,如下所示:

  • 高级标准:和
    • 标准:PRODUCT 等于“ABC”
    • 标准:USER 以“A”开头
    • 高级标准:或
      • 标准:param1 > 5
      • 标准:param2

我在 Java 中创建了两个新组件:AdvancedCriterion.javaSimpleCriterion.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


【解决方案1】:

这个问题解决了,还有一些问题发生了。好吧,就像上面评论的那样,这个问题更像是“AdvancedCriteria”对象的实现问题。与“CommandButton”没有任何联系或提示,只是一个未命名的 getter。

可能添加的行implements Serialiable 有帮助,虽然我不知道具体情况,因为我尝试了很多东西(保存和恢复状态,使用 setter 和 getter 枚举 propKeys 和类似的东西),总的来说这些都不是解决办法。

【讨论】:

    猜你喜欢
    • 2015-01-02
    • 1970-01-01
    • 2011-11-08
    • 2012-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多