部分渲染只能与@form一起使用吗?

发布于 2024-11-06 02:34:32 字数 4782 浏览 0 评论 0原文

我有一个奇怪的情况,使用 @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>

请注意,更新属性使用了 @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. xhtml 文件
  2. JSF Bean 文件
  3. 用户 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

但我注意到的一件事是,n无论我选择什么更新,更新总是以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:0tblUser,网格上的部分渲染效果很好。

我开始认为这是尝试从网格记录内部更新网格时的一个错误。


I have a strange situation where using @parent, or even explicit id-s dont work in the update attribute. But @form works fine.

I've made a very simple test case, that includes a simple grid whose behaviour is like this :

  1. Every record inside the grid has a modify button
  2. After the modify button is clicked, it'll modify the server data, and the button will be gone, since it'll be only rendered if the record has NOT been modified.

The modify button is like this :

<!-- 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>

Notice that the update attribute makes use of @form which makes it work: when the modify button is clicked, it rerenders and disappears.

Substitute it with @this or @parent or the id of the grid, then it will NOT work. For me it's very logical to use the id of the grid in the update attribute, since i would like to refresh the grid after clicking on the buttton.
I tried making use of rowIndexVar="rowIndex" and myGridId:#{rowIndex}:link, but still aint working.

<!-- 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>

Here are the resources for this simple example :

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

Im using tomcat 7, and these are my dependencies :

<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>

Tried out primefaces 3.0.M1 also, but it got the same behavior also.

Please share your ideas. Is this a bug or i did something wrong ?


UPDATE


Hello,

I've just finished some testing, but all still fails.

Test 1 (making use of update=":gridRPBDetails") :

The JSF File :

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

The generated 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>

Test 2 (making use of update=":gridRPBDetails:#{rowIndex}:undoLink") :

The JSF File :

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

The generated 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>

Both tests still fail in terms of clicking the undo button cannot refresh the record of the grid, or even the grid itself.


UPDATE


I've just updated my test using :

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

Notice i used the :mainForm:tblUser, and i've tried the other options and still failed :

  1. :mainForm:tblUser:
  2. :tblUser (when i dont define the form name)
  3. :mainForm:tblUser:#{rowIndex}:linkId

But 1 thing i notice is,nNo matter what i choosed for the update, the update always ends up as 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>

I tried modifying tblUser:0 on the fly using firebug to just tblUser, the partial rendering on the grid works fine.

Im beginning to think that this is a bug when trying to update a grid from inside a grid record.


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

握住你手 2024-11-13 02:34:32

这个问题已在此处中得到解答。

这是答案的引用:

这更像是一个 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>

抱歉更新晚了!

This has been answered in here.

Here is the quote from the answer :

This is more like a mojarra issue, it should work fine with myfaces
without a wrapper. Workaround is to put a wrapper.

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

Sorry for the late update !

憧憬巴黎街头的黎明 2024-11-13 02:34:32

查看生成的 HTML。由于 放置在 中,因此它生成的客户端 ID 类似于这样

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

0是表行索引。

因此,当您在 上使用相对标识符 update="tblUser" 时,它基本上会搜索 someformid:tblUser:0:tblUser更新。但这并不存在。您希望使用以 : 开头的绝对标识符。

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

Look at the generated HTML. Since the <p:commandLink> is placed in a <p:dataTable>, its generated client ID is something like this

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

The 0 is the table row index.

So when you use the relative identifier update="tblUser" on <p:commandLink>, then it will basically search for someformid:tblUser:0:tblUser to update. But this does not exist. You'd like to use an absolute identifier instead, starting with :.

<p:commandLink update=":someformid:tblUser">
护你周全 2024-11-13 02:34:32
<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方法,执行一些操作,更新修改状态。然后执行 update="mytable",链接修改就消失了。

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

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

<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>

Above is the example of link in the datatable that render the dialog.
may be you can try to change

update=":mainform:dialog_content"

to

update=":mainform:mytable"

in this case my tag form is using id mainform, shown as below:

Please note that I've not been trying this. I just have used in my example above to rendering the dialog panel partially. Good luck

Update:
Well I give it a try like this, combine with your updated post

 <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>

And in the backing 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();
}

And it's worked! after I click on the modify button, call the removeDetail method, do some actions, update the modified status. then do update="mytable", and the link modify is gone.

I'm using Mojarra 2.0.4 and primefaces 3.0.M2

FYI, I'm using DataModel in the backing bean, just a simple List
so no rowIndexVar. Maybe when using the DataModel, can produce this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文