`
Virgo_S
  • 浏览: 1137708 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ajax Integration and Support in the ArcGIS Java We

阅读更多
http://edndoc.esri.com/arcobjects/9.2/Java/java/server/web_adf/ajax/ajax_integration.html
Introduction
ArcGIS Server at 9.2 is a complete Web-based GIS developer platform for building server applications that can be consumed by a variety of clients. ArcGIS Server provides a rich application developer framework for the J2EE environment and a set of software components based on the JavaServer Faces (JSF)1 standard. This framework, called the Java Web Application Development Framework (ADF), is a platform for developing centrally managed J2EE-based GIS applications. Along with JSF, the ADF incorporates and extends the Asynchronous Javascript and XML (Ajax) programming model.

The term ajax was introduced by Jesse James Garrett2. It describes a web programming model used to allow content on a browser page to be updated without full postback to the web server and the re-rendering of elements on the page.

This paper covers the architecture of the integrated Ajax framework within the Java Web ADF. This includes the core Java classes supporting Ajax, the client side Javascript library and the framework for adding custom Ajax renderers. Specific use cases will be used to describe how a certain piece works in detail.

This paper assumes knowledge and some experience in developing web applications using Java, JSF, Javascript, XML and Ajax.

This section covers how the Java Web ADF controls work as a whole. Considering that the Map itself may be the center of most GIS applications, we will use the Map Control to walk through and explain the lifecycle of how a map goes from a JSF tag in a JSP page, to being rendered on the browser page as HTML. Next, we will cover how a request is processed to update the map image, for example how a zoom in operation works.

When a user adds the map tag (com.esri.adf.web.faces.taglib.MapTag5) to their JSP page, it is backed by the com.esri.adf.web.faces.component.MapControl JSF component. The map control itself is value bound to the com.esri.adf.web.data.WebMap. The WebMap is part of a com.esri.adf.web.data.WebContext, which maintains reference to all the GIS resources and GIS business objects that are part of the executing application. As part of the response in the request-response lifecycle, the map control generates XML markup through the com.esri.adf.web.faces.renderkit.xml.MapRenderer to represent the state of the map onto the page. The XML is transformed into HTML and a set of Javascript objects using XSL. The map control uses the WEB-INF/classes/xsl/map.xsl which includes the js/esri_map.js file and creates the EsriMap Javascript object.

To support the serverside controls and allow the development and customization of applications on the web, the Java Web ADF provides an extensive Javascript library6. This collection of objects includes the EsriMap object. The Javascript objects are initialized as part of the unload event of the HTML page. The Javascript objects manipulate the HTML Document Object Model (DOM) and render the controls onto the page. In the case of the map, the GIS resources are added to the EsriMap object as EsriMapSourceDynamic & EsriMapSourceTile Javascript objects.

The Javascript library also provides a range of behaviors or actions (EsriAction) that can be used on the map. For example, the EsriMapRectangle allows users to draw a rectangle on the map control. When a user draws the rectangle to trigger a zoom in operation, the screen coordinates of this rectangle are sent to the server. The JSF key-value pair of mapid=mapid lets the controls know that the map control is responsible for processing this operation. The mapid_mode=id identifies the specific operation to be performed on the map and the appropriate server side tool item is executed. At this point it is back to the request-response cycle.


At this stage, it is important to understand how the JSF request processing lifecycle3 works. The JSF lifecycle is made up of 6 phases, Restore View, Apply Request Values, Process Validation, Update Model Values, Invoke Application and finally Render Response. The JSF implementation processes the components on the form and renders the response back to the browser based on these phases. The Restore View & Render Response phases are considered system-level phases and the others, application-level phases. All application-phases can skip the following phases to the Render Response phase by calling javax.faces.context.FacesContext.renderResponse().

It is important for us to understand the Apply Request Values phase. The purpose of this phase is for each component to retrieve its current state. Component values are typically retrieved from the request parameters. Any updated values set by the user interacting with the application in the browser are passed to the appropriate components during this phase.

Another useful method that is used in the client side postback implementation is the javax.faces.component.UICommand.setImmediate().The method sets a flag on the UICommand to process immediately without waiting till the Invoke Application phase. Finally the javax.faces.context.FacesContext.responseComplete() method signals the JSF implementation that the response rendering is complete and the JSF request processing lifecycle should terminate as soon as the current phase is completed.

Lastly it is important to look at the javax.faces.event.PhaseListener interface. Any class that implements this interface and is registered in the lifecycle of the JSF application will be notified at the beginning and ending of processing for the phase, whose id is returned by the PhaseListener.getPhaseId() method.


The Ajax lifecycle is independent of the implementation on the server. This means that the browser sends a request with certain parameters and expects an XML response in a specific format. The response can be generated from any type of JSF PhaseListeners or servlet or even static XML file. We shall now look at how a PhaseListener can be used to process a request and return a response to the web browser for further processing.

When the browser uses the XMLHttpRequest object to send a request to the server, the request follows the standard JSF request processing lifecycle. The components have been restored in the Restore View phase and their state has been updated in the Apply Request Values phase. Since we require the components on the page to be updated, we skip processing in the PhaseListener.beforePhase() method. It is in the PhaseListener.afterPhase() method that we process the request and render the response to the client.

The request parameter should contain all the information required by the PhaseListener. For example, id of the form within which the component to be updated exists, id of the component to be updated. The components are accessible within the javax.faces.component.UIViewRoot as defined in the page. The JSF components can be accessed as children to other javax.faces.component.UIComponents through the UIComponent.findComponent() method. It is necessary to know the hierarchy of the components as laid down in the JSP page to access the correct component. For this reason, it is recommended that you assign ids to all components that require updating through Ajax and other DOM manipulation on the browser.

For example, if the request parameters contain the form and map ids, the javax.faces.component.html.HtmlForm can be obtained as a child of the UIViewRoot and the MapControl as a child of the HtmlForm component. Once we have a handle on the MapControl, it is now possible to get to the WebMap, which is the GIS business object behind the MapControl. The WebMap can be used for some further processing from this point.

Once the processing is done, the XML response must be returned to the client. The com.esri.adf.web.util.XMLUtil class provides several utility methods that can be used to create and populate an XML document. It is recommended to render all XML elements within one root element. The Java Web ADF renders all Ajax responses within a ?lt;response>?element. The com.esri.adf.web.faces.renderkit.xml.ajax.AJAXUtil.writeResponse() method is the preferred method for rendering the XML response back to the client. Once the response XML has been written to the output stream, it is required to call FacesContext.responseComplete() to inform the JSF implementation that the response has been written. If it抯 not written, the JSF lifecycle continues through the following phases till either FacesContext.responseComplete() is called or the RenderResponse phase renders the response.

Once the response is returned to the browser, the XMLHttpRequest object handles calling the appropriate callback function for processing the response and passes itself as reference. The callback function should use the XMLHttpRequest.responseXML to get to the XML document. At this point, the XML document can be traversed using standard DOM4 functions in Javascript and the HTML elements in the browser page get updated.

Use Case: First application (Map Information)7
This application shows how to update some content on the browser page based on the change in the current extent of the map. When running this application, on zooming in/out or panning the map, a request is sent to the server and the extent and scale of the map is retrieved and displayed.


This use case will show how to send a request to the server using XMLHttpRequest. Next, use a PhaseListener to process the request and render an XML response. Finally, using Javascript, parse the XML response to update elements on the browser page.



mapInformation.jsp

This page simply contains a map control and a table with several placeholders to display the extent and scale of the currently visible map. Another thing to note is the call to the init() Javascript function which initializes some behavior in the application.

<body onload="init()">
  <a:map id="map" value="#{mapContext.webMap}" />
  Map Information :
  <table><tbody>
    <tr>
      <td>MinX : </td><td><span id="minx"></span></td>
    </tr><tr>
      <td>MinY : </td><td><span id="miny"></span></td>
    </tr><tr>
      <td>MaxX : </td><td><span id="maxx"></span></td>
    </tr><tr>
      <td>MaxY : </td><td><span id="maxy"></span></td>
    </tr><tr>
      <td>Scale : </td><td><span id="map-scale"></span></td>
    </tr>
  </tbody></table>
</body>


mapInformation.js

This file defines a set of Javascript functions used in this application. The init() function sets up a listener to the map control, to be notified whenever the map is updated.

map.addUpdateListener("mapInformationListener", updateMapInformationRequest);

The updateMapInformationRequest() function sends requests to the server to get the required map information. Before sending the request to the server, however, we need to set up the parameters for the request. First, we need to get the url of the server to which we need to send the request.

var url = EsriUtils.getServerUrl(map.formId);

Next, we need to build the request parameters that are to be sent to the server for processing the request. As part of the list of parameters, we include the parameters from form elements in which the map is rendered.

var params = "mapinformation=mapinformation&formId=" + map.formId + "&mapId=" + map.id + "&" + EsriUtils.buildRequestParams(map.formId);


Next we send the request to the server. In addition to passing the server url, the parameters string, and whether to do POST or do GET, we pass the callback function which must be called when the XMLHttpRequest object is updated.

var xmlHttp = EsriUtils.sendAjaxRequest(url, params, true, function() { updateMapInformationResponse(xmlHttp); });

Also, it is worth noting the parameters that are sent to the server for processing. Here is the breakdown:
  • Mapinformation: mapinformation helps the appropriate phase listener identify whether it is responsible for processing the request
  • formId: map.formId helps the phase listener identify the form within which the map control is rendered
  • mapId: map.id helps the phase listener get the map control from the form

MapInformationPhaseListener.java

The MapInformationPhaseListener is the class that processes the request, gets the map control, its current extent and scale information. It then renders this information as XML and returns response to the client.

The MapInformationPhaseListener implements the methods defined in the PhaseListener interface. Firstly, the PhaseListener.getPhaseId() tells the JSF implementation about the phase during which this PhaseListener is to be notified.

public PhaseId getPhaseId() {
  return PhaseId.APPLY_REQUEST_VALUES;
}

As we saw before, the Apply Request Values phase is the phase where every control has retrieved any updated values from the request parameter.

Next, the PhaseListener.beforePhase() method is unused as we require the values of the controls to be updated before performing any updates.

public void beforePhase(PhaseEvent phaseEvent) {
  //do nothing
}


It is in the PhaseListener.afterPhase() method that the processing of the request is done.

public void afterPhase(PhaseEvent phaseEvent) {
  // Determine if this PhaseListener is responsible for
  // processing request
  // Process the request
  // Render & return response
}

It is recommended practice to first determine if the request is to be processed by this PhaseListener. This can be done by checking if a specific parameter is present in the request. For example, in the case of the MapInformationPhaseListener, check whether the request parameter mapinformation is equivalent to 搈apinformation?

FacesContext facesContext = phaseEvent.getFacesContext();
ExternalContext externalContext = facesContext.getExternalContext();
Map params = externalContext.getRequestParameterMap();

if (! "mapinformation".equals(params.get("mapinformation")))
  return;



The facesContext object refers to the FacesContext instance, of which this PhaseListener is part of. Thus it has access to all the components that are rendered in the view root of the page. We use the request parameters to find the components of interest for our processing. For example find the form and map control on the page.

String formId = (String) params.get("formId");
UIComponent form = facesContext.getViewRoot().findComponent(formId);

String mapId = (String) params.get("mapId");
MapControl mapControl = (MapControl) form.findComponent(mapId);
WebMap map = mapControl.getWebMap();


Next perform the necessary processing with the desired component and GIS business object.

WebExtent extent = map.getCurrentExtent();
double scale = map.getMapScale();


As part of the Ajax response, an XML response is required to be sent back to the client. We will now create the XML document and populate this document.

Document doc = XMLUtil.newDocument();
Element responseElement = XMLUtil.createElement(doc, "response", null, null);
XMLUtil.createElement("minx", Double.toString(extent.getMinX()), responseElement);
XMLUtil.createElement("miny", Double.toString(extent.getMinY()), responseElement);
XMLUtil.createElement("maxx", Double.toString(extent.getMaxX()), responseElement);
XMLUtil.createElement("maxy", Double.toString(extent.getMaxY()), responseElement);
XMLUtil.createElement("map-scale", Double.toString(scale), responseElement);


Once the XML response document has been created and populated with the required information, it is to be written back to the client. Use the AJAXUtil.writeResponse() to write the response.

AJAXUtil.writeResponse(facesContext, doc);


Since the processing of the request and the response is complete, it is necessary to notify the JSF implementation that the rendering of response is complete, and so the JSF lifecycle should terminate at the end of this phase.

facesContext.responseComplete();


At this point, the MapInformationPhaseListener class has completed its work. Finally, in order to register a phase listener in the JSF lifecycle, it needs to be included in the faces-config.xml.

<lifecycle>
  <phase-listener>
    com.esri.arcgis.sample.mapinformation.MapInformationPhaseListener
  </phase-listener>
</lifecycle>


mapInformation.js

At this point, the response is returned back to the updateMapInformationResponse Javascript function. This function is now responsible for parsing the XML and updating the appropriate HTML elements on the page.

var xml = xmlHttp.responseXML;
document.getElementById("minx").innerHTML = xml.getElementsByTagName("minx").item(0).firstChild.nodeValue;
document.getElementById("miny").innerHTML = xml.getElementsByTagName("miny").item(0).firstChild.nodeValue;
document.getElementById("maxx").innerHTML = xml.getElementsByTagName("maxx").item(0).firstChild.nodeValue;
document.getElementById("maxy").innerHTML = xml.getElementsByTagName("maxy").item(0).firstChild.nodeValue;
document.getElementById("map-scale").innerHTML = xml.getElementsByTagName("mapscale").item(0).firstChild.nodeValue;


This use case is now complete. In this use case we saw how to use Javascript to send a request to the server, how to use a PhaseListener to process the request and return an XML response and finally how to process the XML response and update controls on the page.


At this point, we have integrated Ajax into our Java Web ADF application. The Java Web ADF contains several PhaseListeners, which are used to process Ajax requests. But the most important one, which enables Ajax support for all the Web ADF Controls is the com.esri.adf.web.faces.event.PostBackPhaseListener.

The PostBackPhaseListener listens to phase events in the Apply Request Phase. In the beforePhase() method, this class identifies the UICommand that triggered the request and sets it抯 immediate flag to true. It next creates a new instance of the com.esri.adf.web.faces.renderkit.xml.ajax.AJAXResponseRenderer object. With the immediate flag on the command set to true, the execution of the action is triggered and the GIS business objects and controls on the page are updated.

In the afterPhase() method, the PostBackPhaseListener uses the AJAXResponseRenderer and gets the XML response document from AJAXResponseRenderer.renderResponse(). This XML document is written to the response output stream using AJAXUtil.writeResponse(). Next, the immediate flag is reset on the event sources and finally FacesContext.responseComplete() is called.

The AJAXResponseRenderer class is responsible for iterating through the components in a form and calling the appropriate com.esri.adf.web.faces.renderkit.xml.ajax.AJAXRenderer class to render its state to XML. This XML is then parsed by the appropriate Javascript functions to update the elements on the rendered page.

Going back to the MapControl example, when the EsriMap object is rendered onto the browser page, this object registers a tag handler function, EsriControls.addPostBackTagHandler("map", EsriControls.maps[self.id].updateAsync). When the AJAXResponseRenderer is used to render an XML response, if this response document includes a ?lt;map>? tag, this XML element is passed to the EsriMap.updateAsync() function. This function then updates the map control, for example update the image currently displayed on the map to display a zoomed in image. Similarly, other controls such as EsriToc, EsriToolbar, EsriTask and EsriOverview have updateAsync() functions, which update the appropriate controls during postback.

Use Case: Using the AJAXResponseRenderer (Map Zoom)8
When running this application, selecting a zoom factor less than 1.0 zooms into the map and a factor greater than 1.0 will zoom the map out.

In this use case, we will update the state of the WebMap GIS business object, based on some user input. Next, we use the AJAXResponseRenderer to reflect the changes on all the controls rendered in the browser page.

mapZoom.jsp

This page declares the controls to be used in this application. For the sake of simplicity, this application only contains a single map control. We will use a drop down and zoom in or out of the map based on the specified zoom factor.
<select id="zoomFactor" onchange="sendMapZoomRequest(document.getElementById('zoomFactor').value);">
  <option value="0.2">0.2</option>
  <option value="0.4">0.4</option>
  <option value="0.6">0.6</option>
  <option value="0.8">0.8</option>
  <option value="1.0" selected="true">1.0</option>
  <option value="1.2">1.2</option>
  <option value="1.4">1.4</option>
  <option value="1.6">1.6</option>
  <option value="1.8">1.8</option>
  <option value="2.0">2.0</option>
</select>



The Javascript sendMapZoomRequest() function is responsible for sending the request to the server with the zoom factor selected by the user. The param string contains the required parameter 搈apZoom=mapZoom?so that the com.esri.arcgis.sample.mapzoom.MapZoomPhaseListener can determine that it is responsible for processing the request.

var params = "mapZoom=mapZoom&formId=" + map.formId + "&mapId=" + map.id + "&factor=" + factor + "&" + EsriUtils.buildRequestParams(map.formId);


The callback function to process the XML response is the EsriControls.processPostBack() function. This function is the central Javascript function, which delegates the processing of the response XML to each of the controls on the page based on the list of registered tag handlers.

var xmlHttp = EsriUtils.sendAjaxRequest(url, params, true, function() { EsriControls.processPostBack(xmlHttp); });


MapZoomPhaseListener.java

The MapZoomPhaseListener is responsible for processing the request, getting the map control, zooming in/out of the map based on the factor selected by the user and finally using the AJAXResponseRenderer object to render the XML response. This PhaseListener also executes in the Apply Request Values Phase.

public PhaseId getPhaseId() {
  return PhaseId.APPLY_REQUEST_VALUES;
}


It is once again recommended to determine if this PhaseListener is responsible for processing the request.

if (! 搈apZoom?equals((String) paramMap.get(搈apZoom?))
  return;


And similar to the MapInformationPhaseListener, this PhaseListener should use the form and map control ids to get to the MapControl and the GIS business objects that back the MapControl, namely the WebMap and the WebContext.

UIComponent form = facesContext.getViewRoot().findComponent((String)paramMap.get(揻ormId?);
MapControl mapControl = (MapControl) form.findComponent((String) paramMap.get(搈apId?);
WebMap webMap = mapControl.getWebMap();
WebContext webContext = webMap.getWebContext();


Since we are plan on using the AJAXResponseRenderer to update the map control on the page, we first need to create an array of ids to determine the ids of the controls that trigger the change to the application. In our case, it is the map, since the zoom operation is performed on the map.

Vector eventSources = new Vector();
eventSources.add(mapControl.getId());


Next, we shall create an instance of the AJAXResponseRenderer class. When creating an instance of this object, we pass in the faces context, the event sources and the form, that contains the controls we want to update.

AJAXResponseRenderer ajaxRenderer = new AJAXResponseRenderer(facesContext, eventSources, form);


It is important to note that this class is instantiated before any change is made to the GIS business objects. This is done because, when the AJAXResponseRenderer is initialized, it finds all the com.esri.adf.web.faces.renderkit.xml.ajax.AJAXRenderer classes listed in the WEB-INF/ajax-renderers.xml. Next, it iterates through the controls in the form and, based on the class name returned by AJAXRenderer.getControlClass(), it then calls and stores the object returned by calling AJAXRenderer.getOriginalState(). The original state represents the state of the control before it may have been affected by the change.

Next we execute the business logic of zooming in/out of the map control based on the factor selected by the user.

WebExtent webExtent = webMap.getCurrentExtent();
webExtent.expand(Double.parseDouble((String) paramMap.get(FACTOR)));
webMap.setCurrentExtent(webExtent);


Finally in order to update all the com.esri.adf.web.data.WebContextObservers, we call the com.esri.adf.web.data.WebContext.refresh().

webContext.refresh();


Now that all the business objects have been updated based on the zoom operation on the map, we will use the AJAXResponseRenderer instance to render the XML response document back.

Document doc = ajaxRenderer.renderResponse(facesContext);


On calling AjaxRenderer.renderResponse, the AJAXResponseRenderer iterates through the controls in the form once again and calls the AJAXRenderer.renderAjaxResponse and passes appropriate parameters for building the XML document.

Finally, the response is written out and we notify the faces context implementation that the response is complete.

AJAXUtil.writeResponse(facesContext, doc);
facesContext.responseComplete();


At this point, this use case is complete. Since in the calling function the callback function for the request was set to EsriControls.processPostBack, this function now parses the XML response, finds the tags within the root ?lt;response>?tag and calls the appropriate tag handlers to process the XML tag. For example, the ?lt;map>?tag is processed by the EsriMap.updateAsync() function.

In this use case we saw how to use a PhaseListener to change the state of a control and have the change update any other control that is part of the web context. Also we use the AJAXResponseRenderer object to help us render the XML to update the controls on the page.

Use Case: Custom AJAXRenderers (Map Informaton 2)9
Similar to the Map Information use case, when running this application, on zooming in/out or panning the map, the extent and scale information get updated.


Now that we have seen how to develop PhaseListeners and use the AJAXResponseRenderer to process requests and returns responses to the client, we will next see how to write a custom AJAXRenderer.

We will rewrite the Map Information, but this time, instead of triggering a call every time the EsriMap is updated, we will render an XML element as part of the XML response that is rendered as part of the postback response. The advantage here is that since the control is part of the postback process, it does not require a special request-response cycle to update the map information.



mapInformation2.jsp

This page is similar in layout to the mapInformation.jsp, with the map control and table to display the extent and scale information of the map. Also, we shall call the init() function in the html body抯 憃nload?

Map Information :
<table><tbody>
  <tr>
    <td>MinX : </td><td><span id="minx"></span></td>
  </tr><tr>
    <td>MinY : </td><td><span id="miny"></span></td>
  </tr><tr>
    <td>MaxX : </td><td><span id="maxx"></span></td>
  </tr><tr>
    <td>MaxY : </td><td><span id="maxy"></span></td>
  </tr><tr>
    <td>Scale : </td><td><span id="map-scale"></span></td>
  </tr>
</tbody></table>



mapInformation2.js

In the init() function, we will register a function that will process the XML tag element ?lt;map-information-2>?that is returned as part of the client side postback response.

EsriControls.addPostBackTagHandler("map-information-2", mapInformation2TagHandler);


MapInformation2Renderer.java

At this point, we will jump to the com.esri.arcgis.sample.mapinformation2.MapInformation2Renderer class. This class is an AJAXRenderer and is responsible for returning the map抯 extent and scale information to be displayed in the table in the client. A control, for example a map control, can have several AJAXRenderers, although it is the com.esri.adf.web.faces.renderkit.xml.ajax.MapRenderer, which is responsible for rendering the XML element that updates the map control. It is thus recommended not to render tags which are ?lt;map>? ?lt;toc>? ?lt;task>? ?lt;toolbar>?or ?lt;overview>?

We will walk through the methods, in the order that they are called by the AJAXResponseRenderer.

The getControlClass() method returns the class of the component on the page that it is responsible for rendering content for. In this use case since we will get information from the MapControl, we will let the AJAXResponseRenderer give us the map control to work with.

public Class getControlClass() {
  return MapControl.class;
}


Next, the AJAXResponseRenderer calls the getOriginalState() method. This method should return an object representation of the state of the control, such that when later compared, it can be easily determined whether the state has changed. In this case, since we want to update the information on the browser page only if the map抯 extent has changed, we will return the map抯 current extent as original state.

public Object getOriginalState(UIComponent component) {
  MapControl mapControl = (MapControl) component;
  WebMap webMap = mapControl.getWebMap();
  return webMap.getCurrentExtent();
}


Finally, we get to the renderAjaxResponse() method which is called by the AJAXResponseRenderer when the caller calls AJAXResponseRenderer.renderResponse. In this method, we first check whether the extent of the map has changed, if not, we do not render the ?lt;map-information-2>? tag. When writing custom AJAXRenderers, it is recommended to use this validation to prevent unnecessary updates to the components rendered on the page.

if (currentExtent.equals((WebExtent) state))
  return;


If the extent and scale have changed, we render the minx, miny, maxx, maxy and scale of the map to the XML. The AJAXResponseRenderer passes reference to the parentElement of the XML document. This renderer is responsible for rendering the ?lt;map-information-2>?tag as a child of this parent tag.

Element rootElement = XMLUtil.createElement("map-information-2", null, parentElement);


Next, we use the com.esri.adf.web.util.XMLUtil functions to create the XML content elements.

XMLUtil.createElement("minx", String.valueOf(currentExtent.getMinX()), rootElement);
XMLUtil.createElement("miny", String.valueOf(currentExtent.getMinY()), rootElement);
XMLUtil.createElement("maxx", String.valueOf(currentExtent.getMaxX()), rootElement);
XMLUtil.createElement("maxy", String.valueOf(currentExtent.getMaxY()), rootElement);
XMLUtil.createElement("map-scale", String.valueOf(webMap.getMapScale()), rootElement);


WEB-INF/ajax-renderers.xml

At this point the work of the MapInformation2Renderer is complete. In order for the Java Web ADF framework to use this renderer, it must be included in the ajax-renderers.xml file. First we declare a managed bean using the MapInformation2Renderer class.

<managed-bean>
  <managed-bean-name>ajaxMapInformation2Renderer</managed-bean-name>
  <managed-bean-class>com.esri.arcgis.sample.mapinformation2.MapInformation2Renderer</managed-bean-class>
  <managed-bean-scope>none</managed-bean-scope>
</managed-bean>


Next to the <list-entries> for the AJAXRenderers managed bean, we add an entry, whose value is the ajaxMapInformation2Renderer managed bean.

<value>#{ajaxMapInformation2Renderer}</value>


mapInformation2.js

Finally, we need to implement the mapInformation2TagHandler() function which processes the ?lt;map-information-2>?XML tag and updates the appropriate elements on the html page. The EsriControls.processPostBack() function passes the ?lt;map-information-2>?tag element and the list of eventSources as argument to this function.

function mapInformation2TagHandler(xml, eventSources) {
  document.getElementById("minx").innerHTML = xml.getElementsByTagName("minx").item(0).firstChild.nodeValue;
  document.getElementById("miny").innerHTML = xml.getElementsByTagName("miny").item(0).firstChild.nodeValue;
  document.getElementById("maxx").innerHTML = xml.getElementsByTagName("maxx").item(0).firstChild.nodeValue;
  document.getElementById("maxy").innerHTML = xml.getElementsByTagName("maxy").item(0).firstChild.nodeValue;
  document.getElementById("map-scale").innerHTML = xml.getElementsByTagName("map-scale").item(0).firstChild.nodeValue;
}


In this use case, we saw how to write an AJAXRenderer to render XML and use javascript to update custom content or custom component on the page.
  • 大小: 8.2 KB
  • 大小: 11.3 KB
  • 大小: 9.8 KB
  • 大小: 46 KB
  • 大小: 14.5 KB
  • 大小: 58.3 KB
  • 大小: 53.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics