【问题标题】:Partial Rendering will only work with @form?部分渲染仅适用于@form?
【发布时间】:2011-05-10 04:54:02
【问题描述】:

我有一个奇怪的情况,在更新属性中使用@parent,甚至明确的 id-s 都不起作用。但@form 工作正常。

我制作了一个非常简单的测试用例,其中包括一个简单的网格,其行为如下:

  1. 网格内的每条记录都有一个修改按钮
  2. 修改按钮被点击后,会修改服务器数据,按钮会消失,因为只有在记录没有被修改的情况下才会渲染。

修改按钮是这样的:

<!-- this works, since it's using @form in the update attribute -->
<p:column>
    <p:commandLink
        value="modify record" 
        process="@this" 
        action="#{testUserBean.modifyRecord(user)}"
        update="@form"
        rendered="#{not testUserBean.isRecordModified(user)}" />
</p:column>

请注意,update 属性使用了@form,这使它起作用:当单击修改按钮时,它会重新渲染并消失。

用@this 或@parent 或网格的id 代替它,那么它将不起作用。对我来说,在更新属性中使用网格的 id 是非常合乎逻辑的,因为我想在单击按钮后刷新网格。 我尝试使用rowIndexVar="rowIndex" 和myGridId:#{rowIndex}:link,但仍然无法正常工作。

<!-- this does not work -->
<p:column>
    <p:commandLink id="link"
        value="modify record" 
        process="@this" 
        action="#{testUserBean.modifyRecord(user)}"
        update="tblUser"
        rendered="#{not testUserBean.isRecordModified(user)}" />
</p:column>

以下是这个简单示例的资源:

  1. The xhtml file
  2. The JSF Bean file
  3. The user POJO bean

我使用的是 tomcat 7,这些是我的依赖项:

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>

也尝试了 primefaces 3.0.M1,但它也得到了相同的行为。

请分享您的想法。这是一个错误还是我做错了什么?


更新


你好,

我刚刚完成了一些测试,但仍然失败。

测试 1(使用 update=":gridRPBDetails"):

JSF 文件:

<p:commandLink id="undoLink" value="Undo" process="@this"
    action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
    update=":gridRPBDetails"
    rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
    title="Batalkan buang data" />

生成的xhtml:

<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails'});" 
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>

测试 2(使用 update=":gridRPBDetails:#{rowIndex}:undoLink"):

JSF 文件:

<p:commandLink id="undoLink" value="Undo" process="@this"
    action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
    update=":gridRPBDetails:#{rowIndex}:undoLink"
    rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
    title="Batalkan buang data" />

生成的xhtml:

<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails:0:undoLink'});" 
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>

两个测试仍然失败,点击撤消按钮无法刷新网格的记录,甚至无法刷新网格本身。


更新


我刚刚更新了我的测试:

<p:commandLink
    value="modify record" 
    process="@this" 
    action="#{testUserBean.modifyRecord(user)}"
    update=":mainForm:tblUser"
    rendered="#{not testUserBean.isRecordModified(user)}" />

请注意,我使用了:mainForm:tblUser,并且我尝试了其他选项但仍然失败:

  1. :mainForm:tblUser:
  2. :tblUser(当我没有定义表单名称时)
  3. :mainForm:tblUser:#{rowIndex}:linkId

但我注意到的一件事是,无论我选择什么进行更新,更新总是以 tblUser:0

<a onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/test.xhtml',
{formId:'mainForm',async:false,global:true,source:'tblUser:0:j_idt33',
  process:'tblUser:0:j_idt33',
  update:'tblUser:0'
});" href="javascript:void(0);" id="tblUser:0:j_idt33">modify record</a>

我尝试使用 firebug 将 tblUser:0 即时修改为仅 tblUser,网格上的部分渲染工作正常。

当我尝试从网格记录中更新网格时,我开始认为这是一个错误。


【问题讨论】:

    标签: jsf jsf-2 primefaces


    【解决方案1】:

    here 已回答。

    这是答案的引用:

    这更像是一个 mojarra 问题,它应该适用于 myfaces 没有包装。解决方法是放置一个包装器。

      Code:
        <h:form id="frm">
           <p:outputPanel id="wrapper">
               <p:dataTable id="tbl">
               //...
                   <p:commandButton update=":frm:wrapper" />
               //...
               <p:dataTable>
           <p:outputPanel>
        </h:form>
    

    抱歉更新晚了!

    【讨论】:

    • 请接受这个作为正确答案,所以它会保持在顶部并且人们会立即看到它。否则整个问题将难以理解。
    • @Tim Post:我通常接受我的回答。我只是没有意识到我可以比以前更快地做到这一点,我必须等待 2 天才能打勾我自己的答案。谢谢你的建议。
    【解决方案2】:

    查看生成的 HTML。由于&lt;p:commandLink&gt;被放在了&lt;p:dataTable&gt;中,它生成的客户端ID是这样的

    <a id="someformid:tblUser:0:link">
    

    0 是表格行索引。

    所以当你在&lt;p:commandLink&gt;上使用相对标识符update="tblUser"时,那么它基本上会搜索someformid:tblUser:0:tblUser进行更新。但这不存在。您想改用绝对标识符,以 : 开头。

    <p:commandLink update=":someformid:tblUser">
    

    【讨论】:

    • 你好,BalusC。感谢您的建议。我已经用您推荐的测试更新了我的原始帖子。还是失败了,是不是我做错了什么?
    • 您要删除该行吗?你真的应该更新整个表格。
    • 您好,是的,这就是我尝试过的。此问题似乎仅在网格记录尝试在网格本身上更新时发生。请查看我最新测试的更新答案。谢谢。
    【解决方案3】:
    <p:dataTable id="mytable"
           value="#{dataTableWithLinkBean.list}" var="item">
          <p:column>
            <f:facet name="header">
            Code
            </f:facet>
            <p:commandLink actionListener="#{dataTableWithLinkBean.viewDetail}"  
                    oncomplete="dlg.show()" process="@this" 
                             update=":mainform:dialog_content">
                <h:outputText value="#{item.code}"/>
                <f:param name="code" value="#{item.code}"/>
            </p:commandLink>
          </p:column>
        </p:dataTable>
    
    
    
        <p:dialog widgetVar="dlg" modal="true" id="dialog"
             width="300" height="300">
        <h:panelGrid id="dialog_content">
             <h:outputText value="#{dataTableWithLinkBean.selectedCode}"/>
        </h:panelGrid>     
        </p:dialog>
    

    以上是呈现对话框的数据表中的链接示例。 也许你可以尝试改变

    update=":mainform:dialog_content"

    到

    update=":mainform:mytable"

    在这种情况下,我的标签表单使用 id mainform,如下所示:

    请注意,我没有尝试过这个。我刚刚在上面的示例中使用了部分渲染对话框面板。祝你好运

    更新: 好吧,我试试这样,结合你更新的帖子

     <p:dataTable id="mytable"
           value="#{dataTableWithLinkBean.list}" var="item">
          <p:column>
            <f:facet name="header">
            Code
            </f:facet>
            <h:outputText value="#{item.code}"/>
          </p:column>
          <p:column>
            <p:commandLink value="Modify" 
                   action="#{dataTableWithLinkBean.removeDetail(item)}"
                   process="@this" 
                   update="mytable"
                   rendered="#{not dataTableWithLinkBean.isModifier(item)}">
            </p:commandLink>
          </p:column>
        </p:dataTable>
    

    在后台bean中

         public String removeDetail(ClassForTest item){
        for(ClassForTest o: list){
            if(o.equals(item)){
                //do something update to database
                item.setModified(true);
                break;
            }
        }
        return "";
    }
    
        public boolean isModifier(ClassForTest item){
        return item.isModified();
    }
    

    而且成功了!点击修改按钮后,调用removeDetail方法,做一些动作,更新修改状态。然后更新=“mytable”,链接修改就消失了。

    我正在使用 Mojarra 2.0.4 和 primefaces 3.0.M2

    仅供参考,我在支持 bean 中使用 DataModel,只是一个简单的列表 所以没有rowIndexVar。也许在使用DataModel的时候,会产生这个问题。

    【讨论】:

    • 感谢您的想法。在我遇到这个问题之前,我已经尝试过使用您在其他页面上建议的方法,并且确实效果很好。我的这个问题似乎只发生在网格记录尝试在网格本身上更新时。请查看我最新测试的更新答案。
    猜你喜欢
    • 2021-10-16
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    相关资源
    最近更新 更多