@javax.faces.view.ViewScoped调用@PostConstruct on p:commandButton action from p:datatable column facet

时间:2016-10-22 07:56:07

标签: jsf primefaces cdi view-scope

我有一个primefaces datatableaddItem列中的commandButton操作header总是触发CDI @ViewScoped bean @PostConstruct方法,而来自该列的commandButton的动作editItem不是?!

奇怪的是,只有动作方法返回非空字符串才会发生这种情况?!意味着,如果两个方法都返回null,则不调用@PostConstruct方法,但我使用非空字符串,因为单击按钮应显示新的@ViewScoped页面。

我的实际应用程序中的主要问题是,我在@PostConstruct中执行了一些初始化工作,这在页面构建期间应该只发生一次!

datatable.xhtml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">

<f:view>
    <p:messages autoUpdate="true" showDetail="true"/>
    <h:outputLabel value="Datatable Test"/>
    <h:form>
        <p:dataTable var="item" value="#{datatableBean.items}">
            <p:column>
                <f:facet name="header">
                    <p:commandButton value="Add Item" action="#{datatableBean.editItem(null)}"/>
                </f:facet>
                <p:commandButton value="Edit Item" action="#{datatableBean.editItem(item)}"/>
            </p:column>
            <p:column headerText="Id">
                <p:outputLabel value="#{item.id}"/>
            </p:column>
            <p:column headerText="Name">
                <p:outputLabel value="#{item.name}"/>
            </p:column>
        </p:dataTable>
    </h:form>
</f:view>
</html>

addItem.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">

<f:view>
    <h:outputLabel value="Add Item"/>
</f:view>
</html>

editItem.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core">

<f:view>
    <h:outputLabel value="Edit Item"/>
</f:view>
</html>

DatatableBean.java

package my.web.datatable;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@ViewScoped
@Named
public class DatatableBean implements Serializable {

    private List<Item> items = new ArrayList<>();

    @PostConstruct
    private void init() {
        System.out.println(DatatableBean.class.getName() + " -> init()");

        for (int i = 1; i <= 5; i++) {
            items.add(new Item(i, "Item " + i));
        }

        System.out.println(DatatableBean.class.getName() + " <- init()");
    }

    public List<Item> getItems() {
        return items;
    }

    public String editItem(Item item) {
        System.out.println(DatatableBean.class.getName() + " -> editItem(): " + item);
        if (item == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, "add item", null));
            System.out.println(DatatableBean.class.getName() + " <- editItem()");
            return "addItem.xhtml";
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, "edit item", item.toString()));
            System.out.println(DatatableBean.class.getName() + " <- editItem()");
            return "editItem.xhtml";    
        }
    }
}

Item.java

package my.web.datatable;

public class Item {
    private final int id;
    private final String name;

    public Item(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return String.format("[id=%d,name=%s]", id, name);
    }
}

这是关于数据表列标题facet中的命令按钮的错误吗?或者有更好的方法,做我想做的事情吗?

我在Wildfly-10.0.0.Final上使用primefaces 6.0和Mojarra 2.2.12!

更新:删除了记录器;为addItem / editItem调用相同的方法;添加了重定向/转发页面

0 个答案:

没有答案