简体   繁体   English

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

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

This is my problem.这是我的问题。 I have two <p: commandLink> inside a <ui: repeat> .我在<ui: repeat>中有两个<p: commandLink> > 。 I need to update these buttons by simulating checkbox when I click them.当我单击它们时,我需要通过模拟复选框来更新这些按钮。 Updating a <panelGroup> around <ui:repeat> works.围绕<ui:repeat>更新<panelGroup> > 有效。 However for a list with many items, after clicking the button the update, it makes the screen go back to the top of the list making it impracticable to select many items.但是对于一个包含许多项目的列表,在单击更新按钮后,它会使屏幕 go 回到列表顶部,这使得 select 许多项目变得不切实际。 Are there any ways to give an update specific line in <p:commandLink> ?有没有办法在<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 version: 2.1 JSF 版本:2.1
Primefaces version: 3.5 Primefaces 版本:3.5

The trick here is to update only the sections you need - if you update the whole container the browser will reset and refresh from the point where the most recent update happened.这里的技巧是只更新您需要的部分 - 如果您更新整个容器,浏览器将从最近更新发生的位置重置和刷新。 In JSF there are a couple of ways to accomplish what you need.在 JSF 中,有几种方法可以完成您的需要。 More recent versions of JSF (2.3 in particular) has selectors available such as :parent to allow to easier target specific parts of the page to update.更新版本的 JSF(尤其是 2.3)具有可用的选择器,例如:parent ,以便更轻松地针对页面的特定部分进行更新。 With 2.1 you are slightly more limited.使用 2.1,您会受到更多限制。

I made a quick test and came up with a working example of your particular user case.我进行了快速测试,并提出了您特定用户案例的工作示例。 The image below is using Font Awesome and PrimeFaces 3.5;下图使用 Font Awesome 和 PrimeFaces 3.5;

在此处输入图像描述

I slightly tweaked your code and made a complete and working example.我稍微调整了您的代码并制作了一个完整且有效的示例。 The controller and backing bean have been separated into separate classes in this example.在此示例中,controller 和 backing bean 已分离到单独的类中。 First let's take a look at the 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")
        );
    }
}

This defines our data set and uses Lombok to minimize the amount of boilerplate code ( @Data and @RequiredArgsConstructor ).这定义了我们的数据集并使用 Lombok 来最小化样板代码的数量( @Data@RequiredArgsConstructor )。 I also added a selected flag to keep track of if the checkbox is selected or not.我还添加了一个 selected 标志来跟踪复选框是否被选中。 This is then used in the controller bean when selecting and deselecting:然后在选择和取消选择时在 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);
    }
}

Furthermore, here is the view (XHTML) definition:此外,这里是视图 (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>

As you can see we wrap the buttons inside a form and define an container content that we reference in the update attributes of the p:commandLink tags.如您所见,我们将按钮包装在表单中并定义了我们在p:commandLink标记的update属性中引用的容器content Because we are wrapped inside a form the actual id of the panelGroup actually becomes something like j_idt6:9:j_idt8:content with each content id being unique (because each form has a unique id generated).因为我们被包裹在一个表单中,所以 panelGroup 的实际 id 实际上变成了类似于j_idt6:9:j_idt8:content的东西,每个content id 都是唯一的(因为每个表单都有一个唯一的 id 生成)。

This allows us to target and update the data of that row specifically.这使我们能够专门针对和更新该行的数据。

Theoretically you could update the form directly without wrapping it inside a content .从理论上讲,您可以直接update表单,而无需将其包装在content中。 However, doing so interferes with the life-cycle and handling of the form when wrapped inside a ui:repeat .但是,当包裹在ui:repeat中时,这样做会干扰表单的生命周期和处理。 Adding an additional panelGroup and updating that instead, like in this example, solves the issue.添加一个额外的panelGroup并更新它,就像在这个例子中一样,解决了这个问题。

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

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