【问题标题】:How can I refresh a javascript variable, populated by JSF, via ajax?如何通过 ajax 刷新由 JSF 填充的 javascript 变量?
【发布时间】:2015-06-15 07:59:18
【问题描述】:

我想做以下事情:

  1. h:selectOneMenu 中选择一个项目
  2. 通过 ajax 使用新值更新支持 bean
  3. 使用新值运行 Javascript 函数

在下面的代码中,alert(#{backingBean.derivedValue}) 仍然包含上次更改的值(即,当我选择“二”时它是 0,当我选择“一”时它是 4,等等):

<h:form>
    <h:selectOneMenu value="#{backingBean.input1}">
        <f:selectItem itemLabel="One" itemValue="1"/>
        <f:selectItem itemLabel="Two" itemValue="2"/>
        <f:ajax render="@form" onevent="function(data) { if (data.status === 'success') { alert(#{backingBean.derivedValue}) }}"/>
    </h:selectOneMenu>

    Input value: #{backingBean.input1}
    Derived value: #{backingBean.derivedValue}
</h:form>

还有后台豆:

@ManagedBean
@ViewScoped
public class BackingBean {

    private int input1;
    private int derivedValue;

    public int getDerivedValue() {
        return derivedValue;
    }

    public void setDerivedValue(int derivedValue) {
        this.derivedValue = derivedValue;
    }

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
        derivedValue = input1 * 2;
    }
}

有没有办法做到这一点? (顺便说一句,我已经阅读了这个网站上的无数线程,其中类型/某种处理 JSF/ajax/javascript 一起工作,但不是这个特定问题)

【问题讨论】:

  • 删除内联 javascript 并使用不显眼的脚本事件处理程序要简单得多。在命名函数中做你需要的一切
  • 我不适合内联。你能提供一个你在说什么的样本吗?我不熟悉“脚本事件处理程序”的含义。我试过让 onevent="refresh_on_success" 指向 "function refresh_on_success(data)" 但我有同样的问题......
  • 重新编辑 2:我认为你是对的,@wsaxton。看看你页面的 HTML 源代码,看看 Javascript 是怎么说的。
  • @DavidS,HTML 肯定会显示旧值,旧值出现在 javascript 调用中,所以......这当然是一个时间问题。也许 AJAX 标签中的 EL 表达式不像其他标签那样呈现?
  • 我看到了同样的行为,@wsaxton。我可以使用h:outputText 在页面上显示新的durationDerivedValue,但如果我在函数内使用Javascript alert,则会显示旧值。我们可能误解了 EL 的一些基本原理。

标签: javascript ajax jsf


【解决方案1】:

我已成功实施此答案中提出的解决方案Getting backing bean value with Javascript,它使用PrimeFace's RequestContext 在服务器端添加 Javascript 回调参数。

这是我的 Facelets 页面:

<h:form>
    <p:selectOneMenu value="#{backingBean.input1}">
        <f:selectItem itemLabel="One" itemValue="1"/>
        <f:selectItem itemLabel="Two" itemValue="2"/>
        <p:ajax oncomplete="afterLoad(xhr, status, args)"/>
    </p:selectOneMenu>
    <h:outputScript>
        function afterLoad(xhr, status, args) {    
          alert("Input * 2 = " + args.derived);
        }
    </h:outputScript>
</h:form>

这是我的支持豆:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;

@ManagedBean
@ViewScoped
public class BackingBean {

    private int input1;
    private int derivedValue;

    public int getDerivedValue() {
        return derivedValue;
    }

    public void setDerivedValue(int derivedValue) {
        this.derivedValue = derivedValue;
    }

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
        derivedValue = input1 * 2;
        RequestContext.getCurrentInstance().addCallbackParam("derived", derivedValue);
    }
}

(不知道这是不是集成JSF和D3的好方案。)

另见

【讨论】:

  • 这可以作为一种解决方法,但它有点乱。我真的希望有一种 EL 方式来做到这一点。不幸的是,我最终将 JSF 和 D3 完全分开,只使用 URL 在它们之间传递信息。
  • 我理解想要更简单的东西,但我不同意这是一种解决方法或一团糟。它只是将 JSON 参数传递给 Javascript 回调,这就是标准 REST API 的工作方式。这正是 PrimeFace 的 RequestContext 的设计目的,也是支持 JSF ajax 的组件在幕后所做的事情。不过,我知道我想要一个更简单的解决方案——我自己对此并不满意。
猜你喜欢
  • 1970-01-01
  • 2018-11-17
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 2011-09-09
  • 2015-09-27
  • 1970-01-01
相关资源
最近更新 更多