AjaxManager

This article will conclude our discussion of AjaxObject. AjaxManager is a static object that contains all instances of AjaxObjects, handles global AJAX events, and makes retrieving AjaxObject easy. The main need for AjaxManager is to handle the subscription to the abort event of YAHOO.util.Connection. All AJAX abort events are handled uniformly, but the YUI object passed into the callback does not contain the AjaxObject reference. To find the AjaxObject, we need to search all AjaxObjects stored in AjaxManager against their YUI request object. Then delegate to the appropriate AjaxObject._handleFailure function.

Example 1: AjaxManager

(function() {
	// constants
var YU = YAHOO.util,
	CONN = YU.Connect,

	// local namespace
	_ajaxObjectHash = {},
	_ajaxObjectList = [],

	AM = YU.AjaxManager = {
		/**
		 * Fetches the AjaxObject with the provided ID.
		 * @method get
		 * @param id {String} Required. The AjaxObject ID.
		 * @static
		 */
		get: function(id) {
			return _ajaxObjectHash[id];
		},

		/**
		 * Attempts to find the AjaxObject by its last YUI request object.
		 * @method getAjaxObjectByRequest
		 * @param request {Object} Required. YUI Connection request object.
		 * @static
		 */
		getAjaxObjectByRequest: function(request) {
			return _ajaxObjectList.walk(function(ajaxObject) {
				if (ajaxObject._lastRequest && ajaxObject._lastRequest.tId === request.tId) {
					return ajaxObject;
				}
			});
		},

		/**
		 * Register the AjaxObject with the global object manager.
		 * @method register
		 * @param ajaxObject {Object} Required. The newly instantiated AjaxObject.
		 * @static
		 */
		register: function(ajaxObject) {
			var id = ajaxObject.get(rId);

			if (_ajaxObjectHash[id]) {
				throw(Mint.Util.AjaxManager is declaring a duplicate AJAX ID.);
			}
			else {
				_ajaxObjectHash[id] = ajaxObject;
				_ajaxObjectList.push(ajaxObject);
			}
		},

		/**
		 * Subscribe to global AJAX events.
		 * @method subscribe
		 * @param eventName {String} Required. The event name to subscribe to.
		 * @param callback {Function} Required. The callback function.
		 * @param scope {Object} Optional. The execution scope of callback.
		 * @static
		 */
		subscribe: function(eventName, callback, scope) {
			if (CONN[eventName]) {
				CONN[eventName].subscribe(callback, scope);
			}
		}
	};

	AM.subscribe(abortEvent, function(evt, o) {
		var ajaxObject = AM.getAjaxObjectByRequest(o[0]);
		
		if (ajaxObject && ! ajaxObject._lastRequest.doNotLog) {
			ajaxObject._lastRequest.status = -1;
			ajaxObject._handleFailure(ajaxObject._lastRequest);
		}
		
		ajaxObject._lastRequest.doNotLog = false;
	});
}());

AjaxManager maintains two data structures, a array of all available AjaxObjects and an object map of the AjaxObjects by their rId. When each AjaxObject is instantiated it will call register automatically and added to the data structures. The subscribe simply delegates to the custom events available on YAHOO.util.Connection. The get method uses the rId and the _ajaxObjectHash to quickly find the AjaxObject instance, while the getAjaxObjectByRequest iterates through all available AjaxObjects and comapres the YUI tId variable, until the matching AjaxObject is found.

Lastly, AjaxManager subscribes to the global abortEvent of YAHOO.util.Connection. Assuming an AjaxObject is found and the doNotLog property is false, then the _handleFailure function is called. The doNotLog properties is used in conjunction with the abortOnDuplicate configuration property of AjaxObject, which will prevent intentional aborts from executing the _handleFailure function.

The AjaxObject package is available at http://code.google.com/p/yui-ext-mvc/source/browse/trunk/assets/js/widget/AjaxObject.js and a test page at http://www.mattsnider.com/tests/test_ajaxObject.html.