jsf.ajax.request是否忽略了一个选项?

时间:2014-12-19 22:07:48

标签: javascript ajax jsf

我正在尝试使用Java EE 7创建交互式聊天Web应用程序,特别是使用带有ajax的JSF 2.2。

这个想法是总是有一个缓慢的等待异步ajax请求等待 在服务器上为每个客户端。一旦新消息到达服务器, 返回所有等待请求,以便在所有客户端中呈现消息。 完成请求后,客户端将发送新的等待请求。 如果在30秒内没有消息到达,则返回请求以使其成为新消息 可以在旧的一次之前提交。

我可以让它像这样工作:

的index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">

    <h:head>
        <title>async jsf app</title>
        <h:outputScript library="js" name="resendscript.js" />
    </h:head>
    <h:body> 

        async jsf app
        <h:form id="jsfappform">
            say something: 
            <h:inputText id="newmsg" value="#{jsfAsync.newMessage}" />
            <h:commandButton id="sendbut" value="say" action="#{jsfAsync.say}" />
            <br /><br />
            Messages:
            <br /><br />
            <h:outputText id="msgs" value="#{jsfAsync.msgs}" escape="false">
                <h:outputScript>resendRequest()</h:outputScript>
            </h:outputText>            
            <h:commandButton id="reloadbut" value="" action="#{jsfAsync.resend}" style="visibility: hidden">
                <f:ajax execute="@this" render="msgs" onevent="handleAjax" onerror="handleError" /> 
            </h:commandButton>
            <h:commandButton id="clearbut" value="clear" action="#{jsfAsync.clear}" />
            <h:outputScript>resendRequest()</h:outputScript>
        </h:form>
    </h:body>
</html>

resendscript.js:

function handleAjax(data) 
{
    var status = data.status;
    switch(status) 
    {
        case "success": resendRequest();
                        break;
    }
}

function handleError(data) { }

function resendRequest() 
{
    document.getElementById("jsfappform:reloadbut").click();
} 

支持bean JsfAsync.java:

package jsfasync;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;

@ManagedBean
@ApplicationScoped
public class JsfAsync 
{
    private final List<String> messages;
    private final Object wakeup;

    public JsfAsync() 
    {
        wakeup = new Object();
        messages = new ArrayList<String>(); 
    }

    public void setNewMessage(String msg)
    {
        synchronized(messages)  {  messages.add(msg); }            
    }

    public void say()
    {  
        synchronized(wakeup)  {  wakeup.notifyAll();  }
    }

    public void resend()
    {         
        try { 
          synchronized(wakeup)  {  wakeup.wait(30000);  }
        } catch (Exception e) { }    
    }

    public void clear()
    {
        synchronized(messages)  {  messages.clear();  }
        say();
    }

    public String getNewMessage() {  return ""; }

    public String getMsgs()
    {
        StringBuilder msgs = new StringBuilder();
        synchronized(messages)
        {
            for (String m : messages)
            {
                msgs.append(m);
                msgs.append("<br />");
            }        
            return msgs.toString();
        }
    }
}

我想用ajax请求API替换 resendRequest() javascript函数的主体,如下所示:

jsf.ajax.request('jsfappform:reloadbut', null, 
                 {'javax.faces.behavior.event': 'action', 
                  'execute': 'jsfappform:reloadbut', 
                  'render': 'jsfappform:msgs', 
                  'onevent': 'handleAjax',
                  'onerror': 'handleError'});

不幸的是,我无法以这种方式工作。该调用可以执行ajax请求,但似乎忽略了 onevent 选项,并且在此请求完成时未调用事件处理程序。或许,您是否有任何提示如何使其以这种方式运作?

1 个答案:

答案 0 :(得分:3)

对于提示,请检查生成的<h:commandButton id="reloadbut"> HTML源代码。您将看到JSF已将其生成为'onevent': handleAjax。实际上,作为函数引用而不是字符串。

相应修复:

jsf.ajax.request('jsfappform:reloadbut', null, 
                 {'javax.faces.behavior.event': 'action', 
                  'execute': 'jsfappform:reloadbut', 
                  'render': 'jsfappform:msgs', 
                  'onevent': handleAjax,
                  'onerror': handleError});