命令链接中的setPropertyActionListener不起作用

时间:2019-01-18 07:44:10

标签: jpa primefaces

数据表显示我打算能够编辑的条目。为此,我使用命令链接打开一个对话框。 setPropertyActionListener设置CostingType对象,该对象应该可以在对话框中进行修改。但是,该对话框无法获取或保存对象的变量。相反,它显示一个空对象,然后单击“编辑”按钮(在键入字段之后)显示requiredMessage警告。 checkEdit()(仅用于调试目的)也没有被调用。

HTML:

<h:form id="costingTypeForm" >
<p:tabView id="tabView">
<p:tab id="tab1" title="Costing Type">
<h:form id="costingTypeForm" >              
                <p:tabView id="tabView">
                <p:tab id="tab1" title="Costing Type">                                          
                    <p:dataTable
                            id="costingTypeTable"
                            value="#{costingTypeBean.costingTypeList}"
                            var="costingType"
                            rows="#{psmsProp['psms.dataTable.rows']}"
                            paginator="true"
                            paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} {CurrentPageReport}"
                            rowsPerPageTemplate="#{psmsProp['psms.dataTable.rowsPerPage']}"
                            currentPageReportTemplate="Displaying {startRecord}-{endRecord} out of {totalRecords}"
                            style="width:80%; text-align:center;"
                            sortBy="#{costingType.name}"
                            sortMode="single" >

                            <f:facet name="header">  
                                Costing Type

                                <p:commandButton
                                    value="Add"
                                    oncomplete="PF('addCostingTypeDialog').show()"
                                    update="costingTypeForm:tabView:addCostingTypeForm"
                                    icon="ui-icon-plus"
                                    style="float:right;" />

                                <div style="clear:both" />  
                            </f:facet> 
                            <p:column sortBy="#{costingType.name}"
                                filterBy="#{costingType.name}"
                                filterMatchMode="contains"
                                filterFunction="#{filterUtil.containsFilter}"
                                filterStyle="width:80%;"
                                headerText="Name">
                                <p:outputLabel id = "name" value="#{costingType.name}"  />
                            </p:column>                                             
                            <p:column headerText="Description">
                                <p:outputLabel id = "description" value="#{costingType.nameDesc}"  />
                            </p:column>
                            <p:column headerText="Budgeted">
                                <p:outputLabel value="Yes" rendered="#{costingType.budget}" />
                                <p:outputLabel value="No" rendered="#{not costingType.budget}" />
                            </p:column>
                            <p:column headerText="Deleted">
                                <p:outputLabel value="Yes" rendered="#{costingType.del}" />
                                <p:outputLabel value="No" rendered="#{not costingType.del}" />
                            </p:column>             
                            <p:column>
                                <p:commandLink
                                    oncomplete="PF('editCostingTypeDialog').show()"
                                    update=":costingTypeForm:tabView:editCostingTypeForm"
                                    value="Edit" action="#{costingTypeBean.checkEdit}">
                                    <f:setPropertyActionListener target="#{costingTypeBean.editCostingType}" value="#{costingType}"/>
                                </p:commandLink>                                    
                            </p:column>                                 
                            </p:dataTable>                              
                         <p:dialog
                            header="Edit Costing Type"
                            widgetVar="editCostingTypeDialog"
                            modal="true"
                            showEffect="slide"
                            hideEffect="fade"
                            resizable="false"
                            closable="false">
                            <p:outputPanel id="editCostingTypeForm">
                                <p:panelGrid columns="2" cellpadding="5" rendered="#{not empty costingTypeBean.editCostingType}">                                       
                                    <h:panelGroup>
                                        <p:outputLabel value="Name:" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:inputText value="#{costingTypeBean.editCostingType.name}" required="true" requiredMessage="Name is required" />

                                    <h:panelGroup>
                                        <p:outputLabel value="Description:" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:inputText value="#{costingTypeBean.editCostingType.nameDesc}" required="true" requiredMessage="Description is required" />

                                    <p:outputLabel value="Budgeted:" />
                                    <p:selectOneMenu value="#{costingTypeBean.editCostingType.budget}">
                                        <f:selectItem itemValue="true" itemLabel="Yes" />
                                        <f:selectItem itemValue="false" itemLabel="No" />
                                    </p:selectOneMenu>

                                    <h:outputLabel value="Deleted:" />
                                    <p:selectOneMenu value="#{costingTypeBean.editCostingType.del}">
                                        <f:selectItem itemValue="true" itemLabel="Yes" />
                                        <f:selectItem itemValue="false" itemLabel="No" />
                                    </p:selectOneMenu>
                                </p:panelGrid>                                  
                                <p:commandButton
                                    value="Cancel"
                                    actionListener="#{costingTypeBean.cancelChange}"
                                    oncomplete="PF('editCostingTypeDialog').hide();"
                                    icon="ui-icon-close"
                                    style="float:right;margin-top:10px;margin-bottom:10px;" />                                  
                                <p:commandButton
                                    value="Edit"
                                    actionListener="#{costingTypeBean.updateCostingType}"
                                    oncomplete="if(args.update) PF('editCostingTypeDialog').hide();"
                                    update=":costingTypeForm:messages @(.ui-datatable)"
                                    icon="ui-icon-disk"
                                    style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />
                            </p:outputPanel>
                        </p:dialog>
<p:dialog
                            header="Add New CostingType"
                            widgetVar="addCostingTypeDialog"
                            modal="true"
                            showEffect="slide"
                            hideEffect="fade"
                            resizable="false"
                            closable="false">
                            <p:outputPanel id="addCostingTypeForm">
                                <p:panelGrid columns="2" cellpadding="5">
                                    <h:panelGroup>
                                        <p:outputLabel value="Name" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:inputText value="#{costingTypeBean.name}" required="true" requiredMessage="Enter name" />                                        
                                    <h:panelGroup>
                                        <p:outputLabel value="Description:" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:inputText value="#{costingTypeBean.nameDesc}" required="true" requiredMessage="Enter Engine Type" />
                                    <h:panelGroup>
                                        <h:outputLabel value="Budgeted:" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:selectOneRadio value="#{costingTypeBean.budgeted}">
                                        <f:selectItem itemValue="true" itemLabel="Yes" />
                                        <f:selectItem itemValue="false" itemLabel="No" />
                                    </p:selectOneRadio>
                                    <h:panelGroup>
                                        <h:outputLabel value="Deleted:" />
                                        <p:outputLabel value="*" style="color:red;" />
                                    </h:panelGroup>
                                    <p:selectOneRadio value="#{costingTypeBean.deleted}">
                                        <f:selectItem itemValue="true" itemLabel="Yes" />
                                        <f:selectItem itemValue="false" itemLabel="No" />
                                    </p:selectOneRadio>
                                </p:panelGrid>
                                <p:commandButton
                                    value="Cancel"
                                    actionListener="#{costingTypeBean.cancelChange}"
                                    oncomplete="PF('addCostingTypeDialog').hide();"

                                    icon="ui-icon-close"
                                    style="float:right;margin-top:10px;margin-bottom:10px;" />                                  
                                <p:commandButton
                                    value="Save"
                                    actionListener="#{costingTypeBean.addCostingType}"
                                    oncomplete="if(args.add) PF('addCostingTypeDialog').hide(); else PF('addCostingTypeDialog').show();"
                                    update="@form @(.ui-datatable)"
                                    icon="ui-icon-disk"
                                    style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />

                            </p:outputPanel>
                        </p:dialog> 
</p:tab>                                        
                       </p:tabView>
</h:form>

后备豆:

@Component
 @Scope("view")
 public class CostingTypeBean{

private static final Logger LOGGER = LoggerFactory.getLogger(CostingTypeBean.class);

private long costingTypeId;    
private boolean budgeted, deleted;          
private String name, nameDesc;

private CostingType costingType; 
private CostingType editCostingType;

private List<CostingType> costingTypeList;

@Autowired
private CostingTypeService costingTypeService;

/*
getters and setters
*/
// dialog edit
public void updateCostingType(ActionEvent event) {
        RequestContext context = RequestContext.getCurrentInstance();

        if(editCostingType!=null) {
            costingTypeService.saveOrUpdate(editCostingType);
            context.addCallbackParam("update", true);
        }

        else
            context.addCallbackParam("update", false);
 }

 //debug method
 public void checkEdit() {
    LOGGER.debug("Edit listener");
    ViewUtil.showInfo("Edit dialog triggered");
    System.out.println("Edit listener");
}

我该怎么做才能使editCostingTypeDialog反映CostingType对象的字段并能够读取在输入文本区域中键入的值?

2 个答案:

答案 0 :(得分:1)

您的代码可以正常工作。我要做的就是修改一些update=属性(因为我发现未找到目标组件的异常)。用一些随机数据填充并使用上面的代码后,我得到以下内容;

enter image description here

我在Mojarra 2.3.3.99上使用PrimeFaces 6.1和6.2进行了测试。对话框中编辑按钮的支持bean回调也已正确调用。

接下来要检查的一件事-您正在使用哪个JSF实现?是Mojarra还是MyFaces?哪个版本?也许您在特定实现中遇到了一些错误。您的代码绝对没有错。

在处理此问题时,我不妨张贴完整的代码(包括我的修改);

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui" xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Costing type Test</title>
    </h:head>
    <h:body>
        <h:form id="costingTypeForm" >              
            <p:tabView id="tabView">
                <p:tab id="tab1" title="Costing Type">                                          
                    <p:dataTable
                        id="costingTypeTable"
                        value="#{costingTypeBean.costingTypeList}"
                        var="costingType"
                        paginator="true"
                        style="width:80%; text-align:center;"
                        sortMode="single" >

                        <f:facet name="header">  
                            Costing Type
                            <p:commandButton value="Add" oncomplete="PF('addCostingTypeDialog').show()" update="@form" icon="ui-icon-plus" style="float:right;" />
                            <div style="clear:both" />  
                        </f:facet> 
                        <p:column sortBy="#{costingType.name}"
                              filterBy="#{costingType.name}"
                              filterMatchMode="contains"
                              filterFunction="#{filterUtil.containsFilter}"
                              filterStyle="width:80%;"
                              headerText="Name">
                            <p:outputLabel id = "name" value="#{costingType.name}"  />
                        </p:column>                                             
                        <p:column headerText="Description">
                            <p:outputLabel id = "description" value="#{costingType.nameDesc}"  />
                        </p:column>
                        <p:column headerText="Budgeted">
                            <p:outputLabel value="Yes" rendered="#{costingType.budget}" />
                            <p:outputLabel value="No" rendered="#{not costingType.budget}" />
                        </p:column>
                        <p:column headerText="Deleted">
                            <p:outputLabel value="Yes" rendered="#{costingType.del}" />
                            <p:outputLabel value="No" rendered="#{not costingType.del}" />
                        </p:column>             
                        <p:column>
                            <p:commandLink
                                oncomplete="PF('editCostingTypeDialog').show()"
                                update=":costingTypeForm:tabView:editCostingTypeForm"
                                value="Edit" action="#{costingTypeBean.checkEdit}">
                                <f:setPropertyActionListener target="#{costingTypeBean.editCostingType}" value="#{costingType}"/>
                            </p:commandLink>                                    
                        </p:column>                                 
                    </p:dataTable>                              
                    <p:dialog
                        header="Edit Costing Type"
                        widgetVar="editCostingTypeDialog"
                        modal="true"
                        showEffect="slide"
                        hideEffect="fade"
                        resizable="false"
                        closable="false">
                        <p:outputPanel id="editCostingTypeForm">
                            <p:panelGrid columns="2" rendered="#{not empty costingTypeBean.editCostingType}">                                       
                                <h:panelGroup>
                                    <p:outputLabel value="Name:" />
                                    <p:outputLabel value="*" style="color:red;" />
                                </h:panelGroup>
                                <p:inputText value="#{costingTypeBean.editCostingType.name}" required="true" requiredMessage="Name is required" />

                                <h:panelGroup>
                                    <p:outputLabel value="Description:" />
                                    <p:outputLabel value="*" style="color:red;" />
                                </h:panelGroup>
                                <p:inputText value="#{costingTypeBean.editCostingType.nameDesc}" required="true" requiredMessage="Description is required" />

                                <p:outputLabel value="Budgeted:" />
                                <p:selectOneMenu value="#{costingTypeBean.editCostingType.budget}">
                                    <f:selectItem itemValue="true" itemLabel="Yes" />
                                    <f:selectItem itemValue="false" itemLabel="No" />
                                </p:selectOneMenu>

                                <h:outputLabel value="Deleted:" />
                                <p:selectOneMenu value="#{costingTypeBean.editCostingType.del}">
                                    <f:selectItem itemValue="true" itemLabel="Yes" />
                                    <f:selectItem itemValue="false" itemLabel="No" />
                                </p:selectOneMenu>
                            </p:panelGrid>                                  
                            <p:commandButton
                                value="Cancel"
                                actionListener="#{costingTypeBean.cancelChange}"
                                oncomplete="PF('editCostingTypeDialog').hide();"
                                icon="ui-icon-close"
                                style="float:right;margin-top:10px;margin-bottom:10px;" />                                  
                            <p:commandButton
                                value="Edit"
                                actionListener="#{costingTypeBean.updateCostingType}"
                                oncomplete="if(args.update) PF('editCostingTypeDialog').hide();"
                                update="@form"
                                icon="ui-icon-disk"
                                style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />
                        </p:outputPanel>
                    </p:dialog>
                </p:tab>                                        
            </p:tabView>
        </h:form>
    </h:body>
</html>

这是支持bean(示例使用Lombok和Apache Commons);

@Data
@Named
@ViewScoped
public class CostingTypeBean implements Serializable {
    private CostingType costingType;
    private CostingType editCostingType;
    private List<CostingType> costingTypeList;

    @PostConstruct
    private void init() {
        costingTypeList = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            final String name = RandomStringUtils.randomAlphanumeric(10);
            final String nameDesc = RandomStringUtils.randomAlphanumeric(10);
            final boolean budget = RandomUtils.nextBoolean();
            final boolean del = RandomUtils.nextBoolean();

            costingTypeList.add(new CostingType(name, nameDesc, budget, del));
        }
    }

    public void updateCostingType(ActionEvent event) {
        System.out.println("update!");
    }

    public void checkEdit() {
        System.out.println("Edit listener");
    }

    public void cancelChange() {
        System.out.println("Cancel");
    }

    @Data
    @AllArgsConstructor
    public class CostingType {
        private String name;
        private String nameDesc;
        private boolean budget;
        private boolean del;
    }
}

希望这会有所帮助。

答案 1 :(得分:-1)

这是PrimeFaces中的错误(我认为)。 我在一个最小的测试应用程序中搜索了很多测试。无法使用以下星座:

<p:dataTable value="#{bean.list}" var="myVar".....
  <p:ajax event="rowSelect" partialSubmit="true" process="@this" listener="#{bean.doWork(myVar)}"/>

bean.doWork()将始终使用空指针来调用。

玻璃鱼4.1.1 PrimeFaces 6.2

我认为您的问题是相同的。