Richfaces:如何基于事件数据可用后返回的event.rf.data呈现id?

时间:2013-07-03 14:32:14

标签: java javascript jsf richfaces ajax4jsf

我正在研究一些Java JSF和Richfaces 4应用程序,我是所有这些技术的新手,包括Java,所以你能告诉我的一切,甚至基础知识都可以帮助我:)。

我有

  1. a4j:commandButton通过其actionListener属性触发bean方法
  2. 此bean方法发布名为“updateGUI”
  3. 的主题的id列表
  4. 回到视图文件中,有一个a4j:push,它监听这个“updateGUI”主题,子节点a4j:ajax,事件“dataavailable”
  5. 这3点有效。我唯一的问题是我希望a4j:ajax呈现javascript event.rf.data中包含的id,但我没有成功。如果我手工编写id,而不是使用event.rf.data,则会渲染它们。

    这是xhtml:

    <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" template="/templates/template.xhtml">
      <ui:define name="title">RichFaces Sample</ui:define>
      <ui:define name="body">
        <a4j:push address="updateGUI">
          <!-- here, instead of render="main butt0" (the added button and the parent node),
               I'd like to use event.rf.data, a javascript variable containing the ids
               I don't want to call a bean's getter, since the bean could have created/
               updated/deleted other ids, and we could miss old updated ids, and also
               getters are called multiple times (so can't make a FIFO of updated ids) -->
          <a4j:ajax event="dataavailable" limitRender="true" render="main butt0" />
        </a4j:push>
        <h:form id="main">
          <h:inputText value="#{pushtest.text}">
        <a4j:ajax event="change" />
          </h:inputText>
          <a4j:commandButton value="create a new button!" actionListener="#{pushtest.makemodifthread}" />
          <a4j:outputPanel id="status">
            last updated ids: #{pushtest.logupdated_ids}
          </a4j:outputPanel>
          <br />
        </h:form>
      </ui:define>
    </ui:composition>
    

    及其templates / template.xhtml:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j">
    
    <h:head>
        <title>RichFaces Application</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        </h:head>
    
    <h:body>
            <ui:insert name="body">Default content</ui:insert>
    </h:body>
    </html>
    

    这是bean:

    package unit1;
    
    import java.util.Date;
    import java.lang.Thread;
    import java.lang.Runnable;
    
    import java.io.Serializable;
    import javax.faces.bean.ManagedBean;
    
    import javax.faces.bean.ViewScoped;
    
    import org.richfaces.application.push.MessageException;
    import org.richfaces.application.push.TopicKey;
    import org.richfaces.application.push.TopicsContext;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import org.richfaces.component.UICommandButton;
    import javax.faces.event.ActionEvent;
    
    @ManagedBean
    @ViewScoped
    public class pushtest {
        // from http://illegalargumentexception.blogspot.fr/2009/02/jsf-working-with-component-ids.html
        private UIComponent findComponent(UIComponent c, String id) {
        if (id.equals(c.getId())) {
        return c;
        }
        java.util.Iterator<UIComponent> kids = c.getFacetsAndChildren();
        while (kids.hasNext()) {
        UIComponent found = findComponent(kids.next(), id);
        if (found != null) {
            return found;
        }
        }
        return null;
        }
    
        public void makemodifthread(ActionEvent event) throws MessageException
        {
        UICommandButton butt = new UICommandButton();
        updated_ids = "butt"+ count;
        butt.setId("butt" + count);
        count++;
        butt.setValue(this.text);
        UIComponent parent = findComponent(FacesContext.getCurrentInstance().getViewRoot(), "main");
        parent.getChildren().add(butt);
        updated_ids += " " + parent.getId();
            TopicKey topicKey = new TopicKey("updateGUI");
            TopicsContext topicsContext = TopicsContext.lookup();
            topicsContext.publish(topicKey, updated_ids);
        }
    
        public String getLogupdated_ids()
        {
        System.out.println("LOG updated ids: " + log_updated_ids);
        return (log_updated_ids);
        }
    
        public String getUpdated_ids()
        {
        System.out.println("updated ids: " + updated_ids);
        if (!updated_ids.isEmpty())
        {
            log_updated_ids = updated_ids;
            updated_ids = "";
            return (log_updated_ids);
        }
        return (updated_ids);
        }
    
        public void setText(String text)
        {
        this.text = text;
        }
    
        public String getText()
        {
        return (text);  
        }
    
        private String text = "button name";
        private String updated_ids = "";
        private String log_updated_ids = "";
        private int count = 0;
    }
    

    再见

1 个答案:

答案 0 :(得分:0)

实际上,我以更简单的方式解决了这个问题,感谢:http://www.coderanch.com/t/562602/JSF/java/assign-JSF-Ajax-Render-attribute#post_text_2554972

FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(target.getClientId());

在bean中,我现在可以添加/更新jsf节点,而不必担心websockets,id getter或其他奇怪的东西。

编辑:实际上,这个解决方案并不完美,我需要将它与a4j:push结合起来。下周有更多信息!