2017-01-14 1 views
1

Моя цель: Мне нравится добавлять некоторую командуLink в качестве дочернего элемента PrimeFaces p:timeline Пользователь должен иметь возможность щелкнуть одну из этих ссылок. Щелчок должен вызвать метод в моем компоненте (CDI, ViewScoped). В методе действия мне нужна информация из щелкнутого элемента на временной шкале. В зависимости от результата метода действия может существовать переход к другому пользовательскому интерфейсу.Параметр, переданный от дочернего элемента p: timeline is null in action method

Моя попытка: Полная форма довольно короткая и простая. Так что я лучше разместить его целиком:

<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» на элементе временной шкалы. Этот идентификатор правильно отображается в пользовательском интерфейсе. Метод действия выполнен, но переданный параметр разрешен на null со стороны сервера.

Я использую ту же самую попытку из внутреннего документа (тот же пользовательский интерфейс, только другая форма), где он работает нормально. Я просто не могу назвать метод действия с такими параметрами, как изнутри p:timeline

На моей странице нет вложенных форм, нет ошибок JavaScript в консоли браузеров. Я также пробовал все комбинации кнопок commandLink/button и action/listenener, хотя тот, который используется в этом примере, искусно то, что я хочу, но с теми же результатами.

Я использую PF 6.0 и Mojarra 2.2.10

Update: Я заметил, некоторые slighty разницу в генерируемой HTML для сгенерированного HTML, когда я использую этот вид commandLink например в datatable.

В 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> 

Я добавил дополнительную информацию nal action для бэк-компонента, который делегирует исходный код.

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

Все еще я просто задаюсь вопросом, что не так с inital подход.

ответ

1

Почему вы не используете

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

В метод onSelect вы можете вызвать openStatusSheet или refactore openStatusSheet для TimelineSelectEvent. Идентификатор можно сохранить в атрибуте data.

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

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

Edit: Второе решение

Для представить идентификатор с пользовательскими компонентами используют p:commandButton с f: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> 

И в свой бэк-боб можно поймать пары, как

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

    ... 
} 

Таким образом, вы можете вставить 2 или более commmandButtons.

+0

tyvm для вашего ответа. Возможно, это будет компромисс для нынешней ситуации. Однако есть несколько проблем с этим. Главным моментом является то, что я ожидаю изменений в пользовательском интерфейсе, где к одному событию времени добавляется более одной командной ссылки. когда я использую событие select на временной шкале, я потеряю эту опцию. – stg

+1

Правильно. Я добавил второе решение для этого варианта использования. – jklee

+0

Передача параметра с помощью f: param сделала трюк! Тем не менее, я не знаю, почему это не работает с первоначальным подходом в моем вопросе. – stg

0

это означает, что ваш timelineitem.roadmapId имеет значение null, а также сделать ваш управляемый bean ViewScope или Session Scope. параметр печати перед прохождением.

+0

Bean * is * ViewScoped. В пользовательском интерфейсе правильный идентификатор отображается как метка на элементе временной шкалы. – stg

Смежные вопросы