从 p:timeline 的子项传递的参数在操作方法中为空

Parameter passed from a child of p:timeline is null in action method

我的目标: 我想添加一些 commandLink 作为 PrimeFaces 的子项 p:timeline 用户应该能够单击其中一个链接。单击应调用我的 bean 中的一个方法(CDI、ViewScoped)。在操作方法中,我需要时间轴中单击项目的信息。根据操作方法的结果,可能会导航到不同的 UI.

我的尝试: 完整的表格非常简短。所以我更好 post 它完全:

<h:form>
  <p:fieldset legend="Upcoming Gates">
    <p:timeline height="200px" style="width: 99%;"
           start="#{facilitatorCockpit.timelineStart}"
           end="#{facilitatorCockpit.timelineEnd}"
           value="#{facilitatorCockpit.timelineModel}"
           var="timelineitem"
           selectable="false"
           zoomable="false"
           moveable="false"                                
           >     
       <h:outputText value="#{timelineitem.systemElement}"/> <br/>
       <p:commandLink action="#{facilitatorCockpit.openStatusSheet(timelineitem.roadmapId)}"
                               process="@this"  value="#{timelineitem.roadmapId}"
                               title="Open Status Sheet"/>         
    </p:timeline>
  </p:fieldset>
</h:form>

当前行为: 正如在 xhtml 中看到的那样,我在时间轴项目上显示了一些 "Id"。此 ID 在 UI 中正确显示。执行了action方法,但是传入的参数在服务端被解析为null

我在数据表中使用了完全相同的尝试(相同 UI,只是形式不同),它运行良好。我只是无法从 p:timeline

内部调用带有这样参数的操作方法

我的页面上没有嵌套表单,浏览器控制台中没有显示 JavaScript 错误。我还尝试了 commandLink / button 和 action/listener 的所有组合,即使示例中使用的组合正是我想要的,但结果相同。

我正在使用 PF 6.0 和 Mojarra 2.2.10

Update:当我使用这种 commandLink 时,我注意到生成的 HTML 与生成的 HTML 有一些细微差别,例如在数据表中。

p:timeline 中,为每个时间线项目生成完全相同的标识符和 JavaScript 调用:

<a id="j_idt88:j_idt94" href="#" class="ui-commandlink ui-widget" 
   aria-label="Open Status Sheet" 
   onclick="PrimeFaces.ab({s:&quot;j_idt88:j_idt94&quot;,p:&quot;j_idt88:j_idt94&quot;});
            return false;" 
   title="Open Status Sheet">FPR 137
</a>
<!-- .... -->
<a id="j_idt88:j_idt94" href="#" class="ui-commandlink ui-widget"
    aria-label="Open Status Sheet" 
    onclick="PrimeFaces.ab({s:&quot;j_idt88:j_idt94&quot;,p:&quot;j_idt88:j_idt94&quot;});
           return false;"
    title="Open Status Sheet">FPR 138

当前解决方案: 基于已接受的答案,我目前的方法现在看起来像这样:

<p:commandLink action="#{facilitatorCockpit.openStatusSheetFromTimeline()}"
    process="@this"
    value="#{timelineitem.phase.label}"
    title="Open Status Sheet"
>         
   <f:param name="id" value="#{timelineitem.roadmapId}" />
</p:commandLink>

我向委托给原始 bean 的支持 bean 添加了一个额外的操作方法。

public String openStatusSheetFromTimeline() {
    Map<String, String> params = FacesContext.getCurrentInstance()
        .getExternalContext()
        .getRequestParameterMap();
    String roadmapId = params.get("id");
    Long id = Long.parseLong(roadmapId);
    return openStatusSheet(id);
}

我仍然想知道最初的方法有什么问题。

这意味着你的 timelineitem.roadmapId 是 null ,也使你的托管 bean ViewScope 或 Session Scope。通过前打印参数。

你为什么不用

<p:ajax event="select" listener="#{facilitatorCockpit.onSelect}"/> ?

您可以在 onSelect-method 中调用 openStatusSheet 或重构 TimelineSelectEvent 的 openStatusSheet。您可以将 id 保存在 data-attribute 中。

public void onSelect(TimelineSelectEvent e) {  
    TimelineEvent timelineEvent = e.getTimelineEvent();  

    // get your Id
    String roadmapId = timelineEvent.getDate.toString();
} 

编辑:第二个解决方案

要使用自定义组件提交 ID,请使用 p:commandButtonf:param

    <p:timeline id="timeline" value="#{timelineBean.model}"
        height="250px" selectable="true" var="item">

        <p:commandButton value="Click #{item}"
            actionListener="#{timelineBean.click()}">
            <f:param name="id" value="#{item}" />
        </p:commandButton>
    </p:timeline>

在你的支持 bean 中,你可以像这样捕获参数吗

public void click() {
    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    String roadmapId = params.get("id");

    ...
}

因此您可以插入 2 个或更多命令按钮。