【问题标题】:Way to store variable in JSF / issue with c:set and ui:param在 JSF 中存储变量的方法 / c:set 和 ui:param 问题
【发布时间】:2017-11-30 15:34:06
【问题描述】:

我试过c:set和ui: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:set 和ui:param 相同。

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

编辑: 以下是我尝试获取存储在我的 bean 中的旧值的方法:

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

【问题讨论】:

  • 从阅读 stackoverflow.com/questions/3342984/… 开始。您不能通过 jstl c:set 在迭代 h/ui/p 组件中分配 var。 thw jstl 在它们之前处理
  • 好的,所以从我在那里读到的内容来看,不可能像我尝试过的那样去做。还有其他方法吗?我现在编辑了我的实体 bean,以便它可以存储旧值并且它可以工作,但我不喜欢这个解决方案。
  • 在你的控制器中保留一个旧实体的实例并与之比较?为什么需要将这个值从 ui 层传递到控制/服务层?它应该已经(制作)在服务器端可用。
  • 我试图将旧值保留在一个额外的实例中,但这不是很好:实体存储在一个集合中。为了获得旧值,我使用表的 rowIndex 来获取所需的实体及其值。不幸的是,这仅在表格未排序(Primefaces)时才有效。如果使用了排序功能,原始集合与我创建旧值实例时的集合不同。因此,当根据索引比较值时,它不再匹配。有什么好办法吗?
  • 而且我不明白您所说的“它应该已经(制成)可用的服务器端”是什么意思。你能详细说明一下吗?也许这可以解决我的问题。

标签: jsf primefaces jsf-2


【解决方案1】:

因此,似乎使用 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);
    }       
}

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

    <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>

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    相关资源
    最近更新 更多