Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > a4j:poll


Автор: 3,14 1.4.2008, 15:17
Ситуация такова, есть bean возвращающий список объектов. У каждого из этих объектов есть список сообщений, к-ый переодически обновляется. Соотвественно нужно эти сообщения выводить. Если каждый раз запрашивать все собщения целиком, до делается это довольно просто:
Код

       <a4j:outputPanel id="msg_tbl">
           <h:form>
            <a4j:poll id="a4j_poll" interval="10000" rendered="true" enabled="true" reRender="msg_tbl"/>
           </h:form>
       <table bgcolor="#000000" cellspacing="1" cellpadding="3" border="0">
            <c:forEach var="cmd" items="#{cmdManagerBean.commands}">
             <tr>
                 <td bgcolor="#C0C0C0" valign="top">
                     <b>#{cmd.description}</b><br/>
                 </td>
                 <td bgcolor="#FFFFFF">
                     <c:forEach var="msg" items="#{cmd.messages}">
                             #{msg.message}
                     </c:forEach>
                     <c:if test="#{cmd.state == 2}">
                         <h:form>
                                <br/>
                                <h:commandLink actionListener="#{cmdManagerBean.close}">
                                    <h:outputText value="Close" />
                                    <f:param id="closeCmdId" name="cmdId" value="#{cmd.id}" />
                                </h:commandLink>
                                <br/>
                        </h:form>
                     </c:if>
                 </td>
             </tr>
            </c:forEach>
        </table>
       </a4j:outputPanel>

но целокм каждый раз отсылат ьвсё не хочется. Хотелось бы запрашивать все сообщения только в первый раз, а дальше запршивать только новые. Вот как сделать такое, не понятно  smile 

Автор: alexsmirnov 3.4.2008, 08:47
Можно через JavaScript, у a4j:poll есть функция oncomplete - туда можно подставить вызов JavaScript, который добавляет сообщение к списку.
Ему можно передать параметер  :
Код

 AjaxContext.getCurrentInstance().setResponseData(foo);

и обработать :
Код

...  oncomplete="addMessege(request,event,data)" ....

Автор: 3,14 4.4.2008, 12:00
alexsmirnov, а можно какой нибудь пример использования данной конструкции? (полностью код java-обработчика, полностью строка a4j:poll и код JavaScript-кой ф-ии) Google с примерами мне не помог  smile 

Автор: 3,14 8.4.2008, 12:51
Так, вроде разобрался с этим. Остался тольк оодин вопрос: можно ли сделать так, чтоб первый вызов a4j:poll производился сразу после загрузки, а не по истечению таймера? Если кто поможет, буду очень благодарен.

Далее, как это делается (вдруг кому пригодится):
Код

    public void updateLogs(ActionEvent event) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        AjaxContext  ajaxContext  = AjaxContext.getCurrentInstance(facesContext);
        List<CommandMessageBean> data = new Vector<CommandMessageBean> ();
        List<CommandBean> cmds = CommandStore.getInstance().getCommands(getSessionId());
        synchronized (cmds) {
            if (cmds != null) {
                for(CommandBean cmd: cmds) {
                    data.addAll(cmd.getNewMessages());
                }
            }
        }
        ajaxContext.setResponseData(data);
    }
    
    public boolean isNotCompleted() {
        List<CommandBean> cmds = CommandStore.getInstance().getCommands(getSessionId());
        synchronized (cmds) {
            if (cmds != null) {
                for(CommandBean cmd: cmds) {
                    if (cmd.getState() != CommandBean.FINISHED) {
                        return true;
                    }
                };
            };
        };
        return false;
    }



Сама страница:
Код

       <h:form>
          <a4j:poll id="a4j_poll0" interval="10000" actionListener="#{cmdManagerBean.updateLogs}"   enabled="#{cmdManagerBean.notCompleted}" oncomplete="updateLogs(document, event, data);"/>
           </h:form>
     <table bgcolor="#000000" cellspacing="1" cellpadding="3" border="0">
        <c:forEach var="cmd" items="#{cmdManagerBean.commands}">
         <tr>
             <td bgcolor="#C0C0C0" valign="top">
                            ...
             </td>
             <td bgcolor="#FFFFFF">
                    <div id="cmd_log_#{cmd.id}">
                 </div>
             </td>
         </tr>
        </c:forEach>
       </table>

И код на JavaScript к-ый делает это обновление:
Код

function updateLogs(doc, event, data) {
     for(i = 0; i < data.length; i++) {
      cmd_id = data[i].commandId;
      msg    = data[i].message;
      status = data[i].status;
      msg = msg.replace("\n", "<br/>") + "<br/>";
      ddiv = doc.getElementById('cmd_log_' + cmd_id);
      if (ddiv) ddiv.innerHTML += msg;      
     }
}

Послдений пока не доработан, ибо в IE не отображаются HTML тэги, при добавлении в div.

Автор: anglerhood 8.4.2008, 13:53
Можно добавить джаваСкриптовый эвент onload, например для всей страницы:
Код

<body onload="updateLogs(document, event, data);">


Или обернуть всю страницу в http://www.jboss.org/file-access/default/members/jbossajax4jsf/freezone/docs/tlddoc/a4j/page.html и использовать его атрибут onload.

Автор: 3,14 8.4.2008, 14:37
anglerhood, ИМХО первый вариант работать не будет, всё таки параметры event и data передаются из AJAX. А вот второй вариант посмотрю. 
Пока просто сделал чтоб из interval для запросов возвращался bean-ом, первый раз возращается 0, а затем интервал обновления уже. Но надеюсь что это временное решение, ибо как то криво это.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)