使用c:set和ui:param在JSF / issue中存储变量的方法

时间:2017-11-30 15:34:06

标签: jsf primefaces jsf-2

我尝试了c:setui:param,但最后我认为我做错了。

以下是关键的XHTML部分:

    <h:form id="formTable">
    <p:dataTable editable="true" value="#{types.dataList}" var="datalist" style="width:90%; margin-bottom:20px"
        rows="10" paginator="true" rowsPerPageTemplate="10,25" resizableColumns="true" liveResize="true" tableStyle="width:auto">
        <!-- save the old value for the edit action-->
        <c:set var="oldValue" value="#{datalist.getType()}"/>
        <!-- column for testing purpose-->
        <p:column>
            <h:outputText value="#{oldValue}" />
        </p:column>
        <p:column headerText="Type" sortBy="#{datalist.type}">
            <p:cellEditor>
                <f:facet name="output">
                    <h:outputText value="#{datalist.type}" />
                </f:facet>
                <f:facet name="input">
                    <h:inputText value="#{datalist.type}" binding="#{inputUpdateType}" required="true" />
                </f:facet>
            </p:cellEditor>
        </p:column>
        <p:column headerText="Date" sortBy="#{datalist.lastModifyDate}">
            <h:outputText value="#{datalist.lastModifyDate}"/>
        </p:column>
        <p:column headerText="Edit">
            <p:rowEditor rendered="#{!datalist.dependenciesFound}"/>
            <h:graphicImage value="../images/attention.png" rendered="#{datalist.dependenciesFound}" />
        </p:column>
        <p:column headerText="Delete">
            <p:commandLink action="#{types.delete(datalist.type)}" rendered="#{!datalist.dependenciesFound}" update=":formTable">
                <p:graphicImage url="../images/delete.png" />
                <p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
            </p:commandLink>
            <h:outputText value="Not editable because of dependency" rendered="#{datalist.dependenciesFound}"/>
        </p:column>
        <!-- We edit/update the value here. This is where the old value is needed-->
        <p:ajax event="rowEdit" listener="#{types.update(oldValue, inputUpdateType.value)}"/>
    </p:dataTable>
    <p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
        <p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
        <p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
    </p:confirmDialog>
</h:form>

我希望这有点可以理解。 对于我的项目,我使用的是Primefaces 6.1。要编辑此表中的行,我需要保存旧值并在底部的ajax调用中使用该值。我需要这个,因为应用程序或者更确切地说这背后的数据库表需要它(id是这个值)。 编辑后的值存储在变量inputUpdateType

我的问题

当我输入新值并点击编辑时,当应用程序进入更新方法时,旧值与编辑后的值相同。我在更新方法中创建了一个日志条目来验证传递的值。与c:setui:param相同。

我做错了什么?我怎样才能做到这一点?

修改 以下是我尝试将旧值存储在我的bean中的方法:

<p:ajax event="rowEdit" listener="#{types.update(types.dataListOld.toArray()[rowIndex].getType(), inputUpdateType.value)}"/>

1 个答案:

答案 0 :(得分:0)

因此,似乎在ajax中,值将在执行方法之前更新。因此,旧值在服务器端不再可用。不幸的是,将变量存储在JSF中也是不可能的,因为c:set将在JSF标记之前处理,因此不会保存任何值(没有作用域的作用域,最后也会在方法执行之前更新) )。

为了完成这一切,我使用单元格修改模式而不是默认的行编辑模式。有了这个,我就能得到新旧价值:

    public void onCellEdit(CellEditEvent event){
    //We will call this method on edits made to a cell
    //Values are stored in a Arraylist. Number of entries depend on how many components there are in the edited cell/facet
    //Here we have two because in "input" there are two components defined (although both are rendered at the same time).
    @SuppressWarnings("unchecked")
    ArrayList<String> oldValue = ((ArrayList<String>)(event.getOldValue()));
    @SuppressWarnings("unchecked")
    ArrayList<String> newValue = ((ArrayList<String>)(event.getNewValue()));

    //In the end both entries have the same value, so we just take the first.
    if(newValue != null && !newValue.equals(oldValue)) {
        update(oldValue.get(0), newValue.get(0));
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue.get(0) + ", New:" + newValue.get(0));
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }       
}

这就是为什么我的值列表中有两个条目(“input”中的两个组件):

    <f:facet name="input">
        <h:inputText value="#{datalist.type}" binding="#{inputUpdateType}" required="true" rendered="#{!datalist.dependenciesFound}"/>
        <h:outputText value="#{datalist.type}" rendered="#{datalist.dependenciesFound}"/>
    </f:facet>
</p:cellEditor>