简体   繁体   English

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

[英]is onevent option ignored for jsf.ajax.request?

I am trying to create an interactive chat web application using Java EE 7, in particular using JSF 2.2 with ajax. 我正在尝试使用Java EE 7创建交互式聊天Web应用程序,特别是使用带有ajax的JSF 2.2。

The idea is that there is always one slow pending asynchronous ajax request waiting on the server for each individual client. 我们的想法是,服务器上每个客户端始终有一个缓慢的待处理异步ajax请求。 Once a new message arrives to the server, all waiting requests are returned so that the messages are rendered in all clients. 一旦新消息到达服务器,将返回所有等待请求,以便在所有客户端中呈现消息。 On completion of the requests, new waiting requests are sent by the clients. 完成请求后,客户端将发送新的等待请求。 If no message arrives within 30 seconds, the request is returned so that a new one can be submitted before the old one times out. 如果在30秒内没有消息到达,则返回请求,以便在旧的一次之前提交新请求。

I could make it work like this: 我可以让它像这样工作:

index.xhtml: 的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: 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();
} 

backing bean JsfAsync.java: 支持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();
        }
    }
}

I would like to replace the body of the resendRequest() javascript function with the ajax request API as follows: 我想用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'});

Unfortunately, I can't get it work this way. 不幸的是,我不能这样做。 The call can perform the ajax request, but it seems the onevent option was ignored, and the event handler was not called when this request completed. 该调用可以执行ajax请求,但似乎忽略了onevent选项,并且在此请求完成时未调用事件处理程序。 Do you, perhaps, have any hints how to make it work in this way? 或许,您是否有任何提示如何以这种方式使其工作?

For hints, check the generated HTML source of <h:commandButton id="reloadbut"> . 对于提示,请检查生成的<h:commandButton id="reloadbut"> HTML源代码。 You'll see that JSF has generated it as 'onevent': handleAjax . 您将看到JSF已将其生成为'onevent': handleAjax Indeed, as function reference instead of as a string. 的确,作为函数引用而不是字符串。

Fix it accordingly: 相应修复:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM