ADF 如何从bean 触发一个clientListener?

ADF how to trigger a clientListener from the bean?

这是我正在尝试做的事情。

我的 ADF 页面嵌入在网页中,我必须在父页面中设置一些值 window。

为此,我有一个 javascript 函数可以很好地完成工作。 要获得我需要推送的值,我必须使用一些取决于用户点击的参数调用外部 API。

我在我的管理 bean 中实现调用,我获取值并将其推送到我页面上的输入字段中。

我还在输入字段上设置了一个 clientListener(valueChange) 来调用我的 javascript 函数。

理论上应该没问题。

问题是,在用户调用调用 API 的 serverListener 事件后,当值被推入输入字段时,不会调用 clientListener。

我已经让该字段可见以进行测试,我可以自己输入值并且它可以工作,但是当 bean 将值推送到字段中时,valueChange 事件不会被触发。

这里的问题是 如何在 bean 获取值后触发事件,或者如何直接从 bean 调用 javascript 函数?

这是我使用的代码示例

<af:resource type="javascript">
     function pushValue(evt){
          // push values to parent page
          window.external.main.setFieldValue("fieldName", evt.getSource().getValue());
     }
     function callServerAPI(){
         // call the serverListener
         AdfCustomEvent.queue(it2, "callAPI", {somevalues}, true);
     }
</af:resource>
<af:inputText label="My hidden field" 
              id="it2" 
              binding="#{pageFlowScope.MyAppBean.hiddenField}"
              clientComponent="true">
              <af:clientListener method="pushValue" type="valueChange"/>
              <af:serverListener type="callAPI"
                                method="#{pageFlowScope.MyAppBean.callAPI}"/>
</af:inputText>

这是 bean 的示例

private RichInputText hiddenField;
public void callAPI(ClientEvent clientEvent) throws Exception {

    String fieldValue = clientEvent.getParameters().get("somevalues").toString();

    try {

        // call the API and get the value needed in the hidden field
        hiddenField.setValue(fetchValue(fieldValue));

    } catch (Exception e) {
        e.printStackTrace();
    }

    // refresh field
    AdfFacesContext.getCurrentInstance().addPartialTarget(hiddenField);        

}

在此先感谢您的帮助!

本文https://cedricleruth.com/how-to-execute-client-javascript-in-an-adf-java-bean-action/回答您的问题:"how do I call the javascript function from the bean directly ?"如下:

/*** In YOURJSF.jsf button, or other component that need to execute a javascript on action, add : ****/
<af:commandButton text="ClickMe" id="cb1" actionListener="#{YOURSCOPE.YOURJAVABEAN.clickToExecuteJavascriptAction}"/>

 /*** In YOURJAVABEAN.java class add : ***/
 public void clickToExecuteJavascriptAction(ActionEvent actionEvent) {
  this.executeClientJavascript("console.log('You just clicked : " + actionEvent.getSource() + " ')");
  //Note: if you use a java string value in this function you should escape it to avoid breaking the javascript.
  //Like this : stringValue.replaceAll("[^\p{L}\p{Z}]", " ")
 }

//You should put this function in a util java class if you want to use it in multiple bean
public static void executeClientJavascript(String script) {
 FacesContext facesContext = FacesContext.getCurrentInstance();
 ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
 service.addScript(facesContext, script);
}