JSF <h:commandbutton>,<f:ajax>没有在@ViewScoped bean上执行,但<a4j:ajax>工作</a4j:ajax> </f:ajax> </h:commandbutton>

时间:2012-05-01 10:38:19

标签: ajax jsf button jsf-2 richfaces

我在/subviews/document-tree.xhtml处有一个Facelets子视图,它为<rich:tabPanel>客户端上的每个标签呈现一棵树。页面和子视图基于JSF 2和RichFaces 4。

<ui:composition ...>
  <rich:tree value="#{rootNode}" var="treeNode" id="#{treeId}">

    <rich:treeNode ... id="chapternode">

      <h:panelGrid columns="2">
        <rich:outputText value="#{treeNode.name}" />
        <h:commandLink>
          <h:graphicImage library="images/icons" name="delete.png"  />
          <rich:componentControl target="remove-chapter-popup" operation="show" />
        </h:commandLink>
        <rich:popupPanel modal="true"
                         onmaskclick="#{rich:component('remove-chapter-popup')}.hide(); return false;"
                         id="remove-chapter-popup">
          <f:facet name="header">
            <h:outputText value="Remove chapter?" />
          </f:facet>
          <f:facet name="controls">
            <h:outputText value="X" />
          </f:facet>
          <p>Remove chapter #{treeNode.name}?</p>
          <h:panelGrid columns="2">
            <h:commandButton value="Add"
                             action="#{nodeManager.removeChapterNode(treeNode)}" 
                             onclick="#{rich:component('remove-chapter-popup')}.hide(); return true;">

              <!--f:ajax execute="@this" render="@form" /-->        <!-- never executed! -->
              <a4j:ajax execute="@this" render="@form" />           <!-- this works however! -->

            </h:commandButton>
            <h:commandButton value="Cancel"
                             onclick="#{rich:component('remove-chapter-popup')}.hide(); return false;" immediate="true" />
          </h:panelGrid>
        </rich:popupPanel>
      </h:panelGrid>

    </rich:treeNode>

    ...

  </rich:tree>
</ui:composition>

这基本上显示了树节点的名称以及右侧的图像以供删除。

每个树子视图都放在<rich:tab>中,因此标签面板 具有所需的封闭<h:form>。没有其他嵌套表格(无论如何禁止)。

#{nodeManager.removeChapterNode(treeNode)} bean已正确标记为@ViewScoped

现在发生的事情有点奇怪:

使用<f:ajax execute="@this" ... />时,按钮从不执行,而使用<a4j:ajax execute="@this" ... /> 始终有效。

为什么呢?这有什么不对?

根据他们自己的话,RichFaces <a4j:ajax> 100%基于JSF 2 <f:ajax>这一事实,这没有多大意义。

这可能是我正在使用的JSF 2.1.7 中的错误吗? (JBoss AS 7.1.1.Final附带的实现)

2 个答案:

答案 0 :(得分:0)

这是减少的差异:

<form id="tree-form" name="tree-form" method="post" action="/pqgenerator2/debug.jsf" enctype="application/x-www-form-urlencoded">
 ...
  <table style="margin: 0 auto;">
    <tbody>
      <tr>
- <td><input id="tree-form:sorting-tree-one:real root:j_idt34" type="submit" name="tree-form:sorting-tree-one:real root:j_idt34" value="Fortfahren" onclick="jsf.util.chain(this,event,'RichFaces.$(\'tree-form:sorting-tree-one:real root:add-root-chapter-popup\').hide(); return true;','mojarra.ab(this,event,\'action\',\'@this tree-form:sorting-tree-one:real root:new-root-chapter-name-input\',\'@form\')');return false" /></td>
+ <td><input id="tree-form:sorting-tree-one:real root:j_idt34" type="submit" name="tree-form:sorting-tree-one:real root:j_idt34" value="Fortfahren" onclick="jsf.util.chain(this,event,'RichFaces.$(\'tree-form:sorting-tree-one:real root:add-root-chapter-popup\').hide(); return true;','RichFaces.ajax(this,event,{&quot;parameters&quot;:{&quot;javax.faces.behavior.event&quot;:&quot;action&quot;,&quot;org.richfaces.ajax.component&quot;:&quot;tree\\u002Dform:sorting\\u002Dtree\\u002Done:real root:j_idt34&quot;} ,&quot;sourceId&quot;:this} )');return false" /></td>
      </tr>
    </tbody>
  </table>
...

- </div></span></span></div></div><input type="hidden" name="tree-form:sorting-tree-one__SELECTION_STATE" id="tree-form:sorting-tree-one__SELECTION_STATE" class="rf-tr-sel-inp" value="" /><script type="text/javascript">new RichFaces.ui.Tree("tree\u002Dform:sorting\u002Dtree\u002Done",{"toggleType":"client"} );</script></div></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="998210192617713914:-9142017502724223608" autocomplete="off" />
+ </div></span></span></div></div><input type="hidden" name="tree-form:sorting-tree-one__SELECTION_STATE" id="tree-form:sorting-tree-one__SELECTION_STATE" class="rf-tr-sel-inp" value="" /><script type="text/javascript">new RichFaces.ui.Tree("tree\u002Dform:sorting\u002Dtree\u002Done",{"toggleType":"client"} );</script></div></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><script type="text/javascript">new RichFaces.ui.Tab("tree\u002Dform:j_idt21",{"index":0,"leave":null,"togglePanelId":"tree\u002Dform:tree\u002Dtabpanel","switchMode":"client","name":"Blah GmbH","enter":null,"disabled":false} )</script></div><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-5805340602741883884:1908800949269113937" autocomplete="off" />
</form>

这里的问题是我为要显示的RichFaces根创建了一个虚拟根节点,我通过RichFaces TreeNodeImpl的{​​{1}}添加了真实的根,其中包含密钥中的空格。

addChild("real root", ...)代码显然可以处理这个问题但不能处理JSF 2 <a4j:ajax>(注意第一个差异部分)。

答案 1 :(得分:0)

空间在身份证中是非法的。另请参阅UIComponent#setId() javadoc。

  

SETID

public abstract void setId(java.lang.String id)
     

设置此UIComponent的组件标识符(如果有)。组件标识符必须遵守以下语法限制:

     
      
  • 不得为零长度字符串。
  •   
  • 第一个字符必须是字母或下划线('_')。
  •   
  • 后续字符必须是字母,数字,下划线('_')或短划线(' - ')。
  •   
     

组件标识符还必须遵守以下语义限制(请注意,setId()实现不强制执行此限制):

     
      
  • 指定的标识符在作为UIComponent的最近祖先NamingContainer的后代的所有组件(包括facet)中必须是唯一的,或者在整个组件树的范围内(如果有)没有这样的祖先是NamingContainer
  •   
     

<强>参数

     
      
  • id - 新组件标识符,或null表示此UIComponent没有组件标识符
  •   
     

<强>抛出

     
      
  • IllegalArgumentException - 如果id在语法上不合法
  •   

似乎RichFaces永远不会根据树的规则验证它。我反过来将其视为RichFaces中的一个错误。 Report它给RichFaces的人。