繁体   English   中英

如何更新里面的按钮<ui: repeat> ?</ui:>

[英]How to update button inside <ui: repeat>?

这是我的问题。 我在<ui: repeat>中有两个<p: commandLink> > 。 当我单击它们时,我需要通过模拟复选框来更新这些按钮。 围绕<ui:repeat>更新<panelGroup> > 有效。 但是对于一个包含许多项目的列表,在单击更新按钮后,它会使屏幕 go 回到列表顶部,这使得 select 许多项目变得不切实际。 有没有办法在<p:commandLink>中给出更新特定行?

<tbody>
    <ui:repeat value="#{myBean.itens}" var="item" varStatus="index">
        <tr class="myCustomClass" id="item#{item.id}">
            <th>
                <p:commandLink
                    rendered="#{myConditionRendered}"
                    actionListener="#{myBean.deselect(item)}"
                    update=":panelGroupArroundId"
                    process="@this">
                    <i style="font-size: 15px;" class="fa fa-check-square-o" />
                </p:commandLink>
                <p:commandLink
                    rendered="#{!myConditionRendered}"
                    actionListener="#{myBean.select(item)}"
                    update=":panelGroupArroundId"
                    process="@this">
                    <i style="font-size: 15px;" class="fa fa-square-o" />
                </p:commandLink>
            </th>
            <td>
                <h:outputText value="#{item.field1}"/>
            </td>
            ...                                                         
        </tr>
    </ui:repeat>
</tbody>

JSF 版本:2.1
Primefaces 版本:3.5

这里的技巧是只更新您需要的部分 - 如果您更新整个容器,浏览器将从最近更新发生的位置重置和刷新。 在 JSF 中,有几种方法可以完成您的需要。 更新版本的 JSF(尤其是 2.3)具有可用的选择器,例如:parent ,以便更轻松地针对页面的特定部分进行更新。 使用 2.1,您会受到更多限制。

我进行了快速测试,并提出了您特定用户案例的工作示例。 下图使用 Font Awesome 和 PrimeFaces 3.5;

在此处输入图像描述

我稍微调整了您的代码并制作了一个完整且有效的示例。 在此示例中,controller 和 backing bean 已分离到单独的类中。 首先让我们看一下backing bean:

@Data @Named @ViewScoped
public class MyBean implements Serializable {
    @Data @RequiredArgsConstructor
    public static class Item {
        @NonNull private String name;
        private boolean selected;
    }

    private List<Item> items;

    @PostConstruct
    private void init() {
        items = List.of(new Item("a"), new Item("b"), new Item("c"),
            new Item("d"), new Item("e"), new Item("f"), new Item("g"), 
            new Item("h"), new Item("i"), new Item("j")
        );
    }
}

这定义了我们的数据集并使用 Lombok 来最小化样板代码的数量( @Data@RequiredArgsConstructor )。 我还添加了一个 selected 标志来跟踪复选框是否被选中。 然后在选择和取消选择时在 controller bean 中使用:

@Data @Named @RequestScoped
public class MyBeanController {
    @Inject
    private MyBean myBean;

    public void select(Item item) {
        item.setSelected(true);
    }

    public void deselect(Item item) {
        item.setSelected(false);
    }
}

此外,这里是视图 (XHTML) 定义:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Button update in UI repeat example</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.0/css/font-awesome.css" />
    </h:head>
    <h:body>
        <table>
            <tbody>
                <ui:repeat value="#{myBean.items}" var="item">
                    <tr style="float: left; padding-right: 10px">
                        <th>
                            <h:form>
                                <h:panelGroup id="content">
                                    <p:commandLink rendered="#{item.selected}"
                                        actionListener="#{myBeanController.deselect(item)}"
                                        update="content" process="@this">
                                        <i class="fa fa-check-square-o" />
                                    </p:commandLink>
                                    <p:commandLink rendered="#{!item.selected}"
                                        actionListener="#{myBeanController.select(item)}"
                                        update="content" process="@this">
                                        <i class="fa fa-square-o" />
                                    </p:commandLink>
                                </h:panelGroup>
                            </h:form>
                        </th>
                        <td><h:outputText value="#{item.name}"/></td>                                                       
                    </tr>
                </ui:repeat>
            </tbody>
        </table>
    </h:body>
</html>

如您所见,我们将按钮包装在表单中并定义了我们在p:commandLink标记的update属性中引用的容器content 因为我们被包裹在一个表单中,所以 panelGroup 的实际 id 实际上变成了类似于j_idt6:9:j_idt8:content的东西,每个content id 都是唯一的(因为每个表单都有一个唯一的 id 生成)。

这使我们能够专门针对和更新该行的数据。

从理论上讲,您可以直接update表单,而无需将其包装在content中。 但是,当包裹在ui:repeat中时,这样做会干扰表单的生命周期和处理。 添加一个额外的panelGroup并更新它,就像在这个例子中一样,解决了这个问题。

暂无
暂无

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

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