gpt4 book ai didi

jsf - 使用a4j :support to update the model and view,准备下一个按钮/提交 Action

转载 作者:行者123 更新时间:2023-12-04 16:12:53 25 4
gpt4 key购买 nike

问题

我们有一个用于企业应用程序的基于wing的前端,现在正在为其实现一个(现在更简单的)JSF/Seam/Richfaces前端。

有些页面包含一些字段,这些字段在编辑后应导致其他字段发生变化。我们需要将此更改立即显示给用户(即他们不必按按钮或其他任何操作)。

我已经使用h:commandButton并通过将onchange="submit()"添加到导致其他字段更改的字段中来成功实现了此操作。这样,当他们编辑字段时就会提交表单,其他字段也会随之更新。

这在功能上可以正常工作,但是特别是当服务器承受大量负载(经常发生)时,表单提交可能会花费很长时间,并且我们的用户在此期间一直在继续编辑字段,然后当对onchange="submit()"请求的响应被回复时被渲染。

为了解决这个问题,我希望能够实现以下目标:

  • 在编辑字段时,如果需要,将仅处理字段,仅重新渲染仅修改字段的字段(这样,用户在此期间所做的任何其他编辑都不会丢失)。
  • 按下按钮后,的所有字段都将按照常规方式处理并重新呈现。

  • (不稳定)解决方案

    好的,我认为可能最简单的是先显示我的页面的一部分。请注意,这只是摘录,某些页面将具有许多字段和许多按钮。
    <a4j:form id="mainForm">
    ...
    <a4j:commandButton id="calculateButton" value="Calculate" action="#{illustrationManager.calculatePremium()}" reRender="mainForm" />
    ...
    <h:outputLabel for="firstName" value=" First Name" />
    <h:inputText id="firstName" value="#{life.firstName}" />
    ...
    <h:outputLabel for="age" value=" Age" />
    <h:inputText id="age" value="#{life.age}">
    <f:convertNumber type="number" integerOnly="true" />
    <a4j:support event="onchange" ajaxSingle="true" reRender="dob" />
    </h:inputText>
    <h:outputLabel for="dob" value=" DOB" />
    <h:inputText id="dob" value="#{life.dateOfBirth}" styleClass="date">
    <f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{userPreference.timeZone}" />
    <a4j:support event="onchange" ajaxSingle="true" reRender="age,dob" />
    </h:inputText>
    ...
    </a4j:form>

    更改 age的值会导致 dob的值在模型中更改,反之亦然。我使用 reRender="dob"reRender="age,dob"来显示模型中更改的值。这很好。

    我还使用全局队列来确保AJAX请求的排序。

    但是,在我单击页面上的其他位置或按Tab键或其他操作之前, onchange事件不会发生。当用户在 age中输入一个值,然后按 calculateButton 而不用单击页面上的其他位置或按Tab键时,这会导致问题。

    因为我可以看到 onchange的值发生了更改,所以 dob事件确实确实首先发生了,但是在执行 calculateButton请求时,这两个值随后又恢复了。

    因此,最后是一个问题:是否有一种方法可以确保在发出 calculateButton请求之前完全更新模型和 View ,以使其不还原它们?自从我使用AJAX队列以来,为什么还没有发生这种情况?

    解决方法

    有两种策略可以解决此限制,但是它们都需要在facelet代码中膨胀,这可能会使其他开发人员感到困惑并引起其他问题。

    解决方法1:使用a4j:support

    该策略如下:
  • ajaxSingle="true"属性添加到calculateButton中。
  • 将具有a4j:support属性的ajaxSingle="true"标签添加到firstName

  • 第一步确保 calculateButton不会覆盖 agedob中的值,因为它不再处理它们。不幸的是,它具有副作用,即它也不再处理 firstName。添加第二步以通过在按下 firstName之前处理 calculateButton来消除这种副作用。

    请记住,尽管可能有20多个字段,例如 firstName。用户填写表格可能会导致20多个请求到服务器!就像我之前提到的那样,这也会使其他开发人员感到困惑。

    解决方法2:使用进程列表

    感谢@DaveMaple和@MaxKatz提出了此策略,它如下:
  • ajaxSingle="true"属性添加到calculateButton中。
  • process="firstName"属性添加到calculateButton中。

  • 第一步可以达到与第一种解决方法相同的效果,但是具有相同的副作用。这次,第二步确保在按下 firstName时对 calculateButton进行处理。

    再次提醒您,尽管可能有20多个字段(例如 firstName)包含在此列表中。就像我之前提到的那样,这也可能会使其他开发人员感到困惑,特别是因为列表必须包含某些字段,而没有其他字段。

    年龄和DOB设置者和获取者(以防万一是造成问题的原因)
    public Number getAge() {
    Long age = null;

    if (dateOfBirth != null) {
    Calendar epochCalendar = Calendar.getInstance();
    epochCalendar.setTimeInMillis(0L);
    Calendar dobCalendar = Calendar.getInstance();
    dobCalendar.setTimeInMillis(new Date().getTime() - dateOfBirth.getTime());
    dobCalendar.add(Calendar.YEAR, epochCalendar.get(Calendar.YEAR) * -1);

    age = new Long(dobCalendar.get(Calendar.YEAR));
    }

    return (age);
    }

    public void setAge(Number age) {
    if (age != null) {
    // This only gives a rough date of birth at 1/1/<this year minus <age> years>.
    Calendar calendar = Calendar.getInstance();
    calendar.set(calendar.get(Calendar.YEAR) - age.intValue(), Calendar.JANUARY, 1, 0, 0, 0);

    setDateOfBirth(calendar.getTime());
    }
    }

    public Date getDateOfBirth() {
    return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
    if (notEqual(this.dateOfBirth, dateOfBirth)) {
    // If only two digits were entered for the year, provide useful defaults for the decade.
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dateOfBirth);
    if (calendar.get(Calendar.YEAR) < 50) {
    // If the two digits entered are in the range 0-49, default the decade 2000.
    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 2000);
    } else if (calendar.get(Calendar.YEAR) < 100) {
    // If the two digits entered are in the range 50-99, default the decade 1900.
    calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 1900);
    }
    dateOfBirth = calendar.getTime();

    this.dateOfBirth = dateOfBirth;
    changed = true;
    }
    }

    最佳答案

    您的bean的作用范围是什么?当执行按钮时,这是一个新请求,如果您的bean在请求范围内,则以前的值将消失。

    关于jsf - 使用a4j :support to update the model and view,准备下一个按钮/提交 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6024130/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com