【问题标题】:Update single row in JSF / Primefaces datatable using AJAX使用 AJAX 更新 JSF/Primefaces 数据表中的单行
【发布时间】:2015-07-19 04:51:38
【问题描述】:

使用 AJAX 时如何更新 p:datatable 中的单行?

我不想更新整个数据表,因为它有很多行并且需要一些时间..

我的布局:

<h:form id="visitForm">
        <p:dataTable id="visitTable" var="visit" value="#{visitBean.findAllVisits()}">

            <p:column headerText="${msgs['email']}"
                <h:outputText value="#{visit.contactDetail.email}"/>
            </p:column>

            <p:column headerText="${msgs['clearance']}" id="clearance">
                <p:commandButton value="${msgs['clearance.ok']}"  actionListener="#{visitBean.makeClearanceNotOk(visit)}"/>
            </p:column>
        </p:dataTable>
    </h:form>

我已经尝试了一些类似 update = "clearance" 等的方法,但它似乎不起作用。

我正在使用 JSF 2.1 和 Primefaces 5.2

【问题讨论】:

标签: ajax jsf primefaces datatable


【解决方案1】:

要么使用OmniFaces 等实用程序库的“ajax”功能,要么使用PrimeFaces Selectors 发挥创意。

在这两种情况下,您都需要访问例如“当前”行或 rowId。但既然你在行中有按钮,那应该不是问题。很遗憾,我没有时间为您创建示例

【讨论】:

  • 我仅限于 PrimeFaces。好吧..问题是“选择当前行”来更新
【解决方案2】:

您可以使用@row(n) 搜索表达式来执行此操作 - 它更新表中的第 n 行。为了更新当前行,您需要将行索引作为参数传递。在&lt;p:dataTable&gt; 上设置rowIndexVar="rowIdx" 属性,然后:

<p:commandButton ... update="@form:visitTable:@row(#{rowIdx})" />

【讨论】:

  • 我已经应用了该指令,但它不起作用,尽管我使用的是 PrimeFaces 6.2 和 JSF 2.2.18。
  • @MohamedEnnahdiElIdrissi 也许我的回答可以帮助你。
【解决方案3】:

我尝试使用 uptate = "@parent:componentAnotherColumn" 并且有效。只更新同一行

 <p:column>    
       <p:selectBooleanCheckbox value="#{atributoVar.booleanValue}">
            <p:ajax process="@this" update="@parent:componentAnotherColumn"/>
       </p:selectBooleanCheckbox>
 </p:column>
 <p:column>                            
     <p:selectBooleanCheckbox id="componentAnotherColumn" value="#{!atributoVar.booleanValue}"/>
 </p:column>                    

【讨论】:

  • 这不是更新整行,只是一个兄弟。
【解决方案4】:

不确定我是否参加聚会迟到了,但让我在这个主题上给我 5 美分,关于如何仅使用 PrimeFaces 的普通 ajax 功能更新一行的内容。

1) 部分更新:我第一种使用 PF 更新特定行中的内容的方法不是完全更新整行,而是更新行内的感兴趣区域。这可以通过定义保持面板并更新它们来实现。例如:

<h:form id="testForm">
    <p:dataTable id="myEntityTable" var="myEntity" value="#{myController.allEntities}">

        <p:column headerText="id">
            <h:outputText value="#{myEntity.id}"/>
        </p:column>

        <p:column headerText="last update">
            <p:outputPanel id="lastUpdatePanel">
                <h:outputText value="#{myEntity.lastUpdate}">
                    <f:convertDateTime pattern="HH:mm:ss" type="date" />
                </h:outputText>
            </p:outputPanel>
        </p:column>

        <p:column headerText="counter">
            <p:outputPanel id="counterPanel">
                <h:outputText value="#{myEntity.counter}"/>
            </p:outputPanel>
        </p:column>

        <p:column headerText="increment">
            <p:commandButton value="+"
                actionListener="#{myController.increment(myEntity)}"
                update="counterPanel, lastUpdatePanel"/>
        </p:column>
    </p:dataTable>
</h:form>

诀窍是更新目标面板(在本例中为片段update="counterPanel, lastUpdatePanel")。结果如下图所示:

2) 实际更新行: 以前的方法通常工作得很好。但是,如果确实需要更新行,则可以遵循先前答案之一中给出的建议并使用 @row 关键字:

<h:form id="testForm">
    <p:dataTable id="myEntityTable" var="myEntity" value="#{myController.allEntities}" rowIndexVar="rowIndex">

        <p:column headerText="id">
            <h:outputText value="#{myEntity.id}"/>
        </p:column>

        <p:column headerText="last update 1">
            <p:outputPanel>
                <h:outputText value="#{myEntity.lastUpdate}">
                    <f:convertDateTime pattern="HH:mm:ss" type="date" />
                </h:outputText>
            </p:outputPanel>
        </p:column>

        <p:column headerText="last update 2">
            <h:outputText value="#{myEntity.lastUpdate}">
                <f:convertDateTime pattern="HH:mm:ss" type="date" />
            </h:outputText>
        </p:column>

        <p:column headerText="counter">
            <p:outputPanel>
                <h:outputText value="#{myEntity.counter}"/>
            </p:outputPanel>
        </p:column>

        <p:column headerText="increment">
            <p:commandButton value="+"
                actionListener="#{myController.increment(myEntity)}"
                update="@form:myEntityTable:@row(#{rowIndex})"/>
        </p:column>
    </p:dataTable>
</h:form>

诀窍是将列中的每个内容保存在 p:outputPanel 中,然后让 update="@form:myEntityTable:@row(#{rowIndex})" 完成这项工作。为了说明这一点,我有意识地将“最后一次更新 2”列不带 outputPanel:

因此,虽然“上次更新 1”和“计数器”列在单击“+”后实际更新,但“上次更新 2”列保持不变。因此,如果您需要更新内容,请使用outputPanel 将其包装起来。同样值得注意的是,保存每一列内容的 outputPanel 不需要明确的 id(如果需要,可以添加)。 为了完整起见,在这些示例中,我使用了 PF 6.2。 backbean 非常简单:

package myprefferedpackage;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class MyController {

    private List<MyEntity> entities;

    @PostConstruct
    public void init() {
        this.entities = new ArrayList<MyEntity>(10);
        for(int i = 0; i < 10; ++i) {
            this.entities.add(new MyEntity(i));
        }
    }

    public List<MyEntity> getAllEntities() {
        return entities;
    }

    public void increment(MyEntity myEntity) {
        myEntity.increment();
    }

    public class MyEntity {
        private int id;
        private int counter;
        private Date lastUpdate;

        public MyEntity(int id) {
            this.id = id;
            this.counter = 0;
            this.lastUpdate = new Date();
        }

        public void increment() {
            this.counter++;
            this.lastUpdate = new Date();
        }

        public int getId() {
            return id;
        }

        public int getCounter() {
            return counter;
        }

        public Date getLastUpdate() {
            return lastUpdate;
        }
    }
}

【讨论】:

猜你喜欢
  • 2018-03-11
  • 2013-09-07
  • 1970-01-01
  • 2015-01-14
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
相关资源
最近更新 更多