【问题标题】:How to call listener or backing bean method after completing a javascript call in jsf?在 jsf 中完成 javascript 调用后如何调用监听器或支持 bean 方法?
【发布时间】:2014-03-25 05:56:04
【问题描述】:

根据我的场景,需要先调用javascript。在 javascript 调用之后,两个隐藏的值将被更新。使用更新的隐藏值,必须调用 Bean 方法。在这种情况下,我同时被称为 javascript 和 bean 方法。所以在我的 bean 方法中,我没有在隐藏字段中获取更新的值。

小细节说明

Textbox(address) 用于输入地址。并有两个隐藏元素,用于根据地址字段存储街道名称和城市名称。

通过 Javascript 调用,从 google maps API (codeAddress()) 收集两个值(街道名称和城市名称)。根据在文本框中输入的地址更新两个隐藏字段(街道和城市)。 Bean 方法必须处理更新后的隐藏值。

但是从我的代码中,Backing bean 和 java 脚本是同时被调用的。所以我没有在支持 Bean 中获得更新的值。

我的代码如下:

JSF 代码

<h:form prependId="false">
    <div id="panel-one">
        <h:outputLabel value="ADDRESS"/>
        <h:inputText type="text" id="address" size="40" value="#{Bean.address}"/>
        <h:inputHidden id="street" value="#{Bean.streetName}" />
        <h:inputHidden id="city" value="#{Bean.city}" />
        <h:commandButton type="submit" value="Verify Address"
            onclick="checkAddress()">
            <f:ajax execute="@form" render="@none" listener="#{Bean.checkAddress()}"/>
        </h:commandButton>
    </div>
</h:form>

Javascript

checkAddress() {
    document.getElementById("street").value = //Setting value from other javascript API;
    document.getElementById("city").value = //Setting value from other javascript API;
}

在上面的 javascript 中收集值并使用两个文本框进行设置。随着更新的值再次调用支持 bean 中的 checkAddress() 方法。 仅供参考: *checkAddress()* 是 AJAX 调用。我在 JSF 的 h:commandButton 中犯了错误,但不知道如何修复它。非常感谢任何帮助。

【问题讨论】:

  • 你为什么不直接删除“actionListener”属性,然后对验证器做同样的事情呢?或者在提交方法中移动该逻辑。
  • @mitpatoliya:你能解释一下吗?提交方法是什么意思?
  • @mitpatoliya :从 commandButton 中删除了 actionListener 属性,并将 listener 属性放置在 ajax 标记中。结果还是一样。是你想说的吗?
  • 既然您需要在用户点击时从 javascript 中填充您的 bean 数据,您为什么不尝试将您的数据从 js 传递到 backing bean?
  • 但是primefaces是可以的,如果你仍然感兴趣,那么你可以使用本文中的方法:stackoverflow.com/questions/18975746/…安全性肯定取决于你的实现。

标签: jsf jsf-2 event-handling jsf-2.2


【解决方案1】:

您提供的代码有几处奇怪:

  • 我认为不需要prependId
  • commandButton 上定义onclick 是个坏主意[tm]
  • 你让自己和/或继承该代码的人感到头疼,因为你有一个 JS 函数一个 bean 方法,两者都称为 checkAddress
  • 您似乎没有根据已触发的操作执行任何操作? (有render="@none"

也就是说,一种应该满足您需要的技巧是隐藏实际按钮并以编程方式单击它:

<h:form id="addrF">
    <h:outputLabel value="ADDRESS"/>
    <h:inputText type="text" id="address" size="40" value="#{bean.address}"/>
    <button class="clickMe">Verify Address</button>

    <h:inputHidden id="street" value="#{bean.streetName}" />
    <h:inputHidden id="city" value="#{bean.city}" />

    <h:commandButton id="submitBtn" style="display:none;">
        <f:ajax execute="@form" render="@none" listener="#{Bean.checkAddress()}"/>
    </h:commandButton>
</h:form>
<h:outputScript>
    $(".clickMe").click(function(ev) {
        ev.preventDefault();
        $.getJSON(
             "https://maps.googleapis.com/maps/api/geocode/json", 
             { address : $("#addrF\\:address").val() },
             function(data) {
                 // set street, city
                 $('#addrF\\:submitBtn').click();
             }
         );
    });
 </h:outputScript>

您可能需要额外的值验证等,并且您对地图 API 的访问可能会有所不同(我根本没有使用过)。重点是:只有在 ajax 调用完成后,您才需要在隐藏的 commandButtonclick()

【讨论】:

    【解决方案2】:

    请尝试在 f:ajax 中使用 event="" 然后使用 onevent 调用 javascript 函数。 事件值将是“点击”,onevent 值将是 javascript 函数的名称。喜欢

    【讨论】:

    • 在上述方法中,我们可以触发javascript调用。但不能在侦听器调用之前调用 javascript 调用。请看一下我的场景。
    • 我用过同样的在我的项目中.. 我的情况是,listner 应该只为下拉列表中的某些选定值调用。我无法停止,所以我在侦听器之前调用了一个javascript函数,它将新值替换为null,而我的侦听器在获取null值时什么也不做。希望它能解决你的问题
    【解决方案3】:

    您可以尝试为 JavaScript setTimeout() 设置延迟

    <h:commandButton type="submit" value="Verify Address"
                onclick="setTimeout(function(){checkAddress()},1000);">
    

    1000 毫秒 = 1 秒,为方便起见,您只需更改该值

    【讨论】:

    • Javascript 必须在 JSF 动作调用之前首先被调用。有用吗?
    • 对不起,我误解了,试试(在你的支持 Bean 中)这个 RequestContext context = RequestContext.getCurrentInstance(); context.update("yourForm:yourComponent");这些行必须在你的 bean 方法的最后
    猜你喜欢
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多