ADF控件ID变化引发JS无法定位控件的解决方法

时间:2023-03-08 22:56:34
ADF控件ID变化引发JS无法定位控件的解决方法
JSFF定义的控件ID到了客户端时往往会改变。例如在JSFF中的一个的ID为"ot1",但是当这个JSFF被嵌入TaskFlow中,并以Region的方式在页面展示时,在浏览器中,此控件的ID就会变成"r1:0:ot1"。
ADF动态修改控件ID的原因其实是为了提供重用性的同时防止控件ID的冲突。试想如果有两个JSFF中分别都有一个,其ID均为ot1,那么当这两个JSFF被引入同一个页面时,其ID值就会冲突。为了解决这个问题,ADF在最终生成的ID中加上了控件所在容器的信息。"r1:0:ot1"中的r1即为JSFF Taskflow所在的Region的名字。
因为ID的变化,导致客户端JS脚本难以定位控件。解决的思路其实很简单,那就是找到一个不变的ID,通过这个ID来定位控件。一个简单的解决方法是给控件定义一个辅助的CSS类,保证这个类名不会重复。示例如下:
<![CDATA[
    <af:resource type="javascript" source="/js/jquery.js"/>
    <af:resource type="javascript">
      function invokeJavaMethod(){
          var clientId = $(".serverListener") [0].id;
          var com = AdfPage.PAGE.findComponentByAbsoluteLocator(clientId);
          AdfCustomEvent.queue(com, "myEvent",  {userName: 'Nicholas'}, true);                               
     }
    </af:resource>
         <a onclick="invokeJavaMethod();">Click me</a>
    <af:outputText value="" id="ot1" visible="false" styleClass="serverListener">
              <af:serverListener type="myEvent" method="#{pageFlowScope.myBean.doCustomEvent}"/>
 </af:outputText>             
   ]]>
以上的方法会有一个潜在的问题,那就是如果同一个Taskflow在同一个页面被多次引用,那么就会有多个元素拥有定位所依赖的CSS。解决方法有两种:
1. 为Taskflow定义一个输入参数,作为CSS的取值。在调用是给Taskflow输入不同的值,就能避免冲突。
2. 可以使用元素的相对位置获取id值。因为无论taskflow如何嵌套和复用,页面元素的相对位置是不变的。
<![CDATA[
<af:resource type="javascript" source="/js/jquery.js"/>
    <af:resource type="javascript">
      function invokeJavaMethod(id){
          var clientId = id.id;
          var com = AdfPage.PAGE.findComponentByAbsoluteLocator(clientId);
          AdfCustomEvent.queue(com, "myEvent",  {userName: id.innerText}, true);                               
     }
    </af:resource>
    <a onclick="invokeJavaMethod(this.nextSibling);" href="#">Click me</a>
    <af:outputText value="#{pageFlowScope.taskName}" id="ot1" visible="false" styleClass="serverListener">
              <af:serverListener type="myEvent" method="#{pageFlowScope.myBean.doCustomEvent}"/>
 </af:outputText>
   ]]>
程序员的基础教程:菜鸟程序员