📄 datasource.js
字号:
/** * Receives raw data response and type converts to XML, JSON, etc as necessary. * Forwards oFullResponse to appropriate parsing function to get turned into * oParsedResponse. Calls doBeforeCallback() and adds oParsedResponse to * the cache when appropriate before calling issueCallback(). * * The oParsedResponse object literal has the following properties: * <dl> * <dd><dt>tId {Number}</dt> Unique transaction ID</dd> * <dd><dt>results {Array}</dt> Array of parsed data results</dd> * <dd><dt>meta {Object}</dt> Object literal of meta values</dd> * <dd><dt>error {Boolean}</dt> (optional) True if there was an error</dd> * <dd><dt>cached {Boolean}</dt> (optional) True if response was cached</dd> * </dl> * * @method handleResponse * @param oRequest {Object} Request object * @param oRawResponse {Object} The raw response from the live database. * @param oCallback {Object} Callback object literal. * @param oCaller {Object} (deprecated) Use oCallback.scope. * @param tId {Number} Transaction ID. */handleResponse : function(oRequest, oRawResponse, oCallback, oCaller, tId) { this.fireEvent("responseEvent", {tId:tId, request:oRequest, response:oRawResponse, callback:oCallback, caller:oCaller}); var xhr = (this.dataType == DS.TYPE_XHR) ? true : false; var oParsedResponse = null; var oFullResponse = oRawResponse; // Try to sniff data type if it has not been defined if(this.responseType === DS.TYPE_UNKNOWN) { var ctype = (oRawResponse && oRawResponse.getResponseHeader) ? oRawResponse.getResponseHeader["Content-Type"] : null; if(ctype) { // xml if(ctype.indexOf("text/xml") > -1) { this.responseType = DS.TYPE_XML; } else if(ctype.indexOf("application/json") > -1) { // json this.responseType = DS.TYPE_JSON; } else if(ctype.indexOf("text/plain") > -1) { // text this.responseType = DS.TYPE_TEXT; } } else { if(YAHOO.lang.isArray(oRawResponse)) { // array this.responseType = DS.TYPE_JSARRAY; } // xml else if(oRawResponse && oRawResponse.nodeType && oRawResponse.nodeType == 9) { this.responseType = DS.TYPE_XML; } else if(oRawResponse && oRawResponse.nodeName && (oRawResponse.nodeName.toLowerCase() == "table")) { // table this.responseType = DS.TYPE_HTMLTABLE; } else if(YAHOO.lang.isObject(oRawResponse)) { // json this.responseType = DS.TYPE_JSON; } else if(YAHOO.lang.isString(oRawResponse)) { // text this.responseType = DS.TYPE_TEXT; } } } switch(this.responseType) { case DS.TYPE_JSARRAY: if(xhr && oRawResponse && oRawResponse.responseText) { oFullResponse = oRawResponse.responseText; } oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseArrayData(oRequest, oFullResponse); break; case DS.TYPE_JSON: if(xhr && oRawResponse && oRawResponse.responseText) { oFullResponse = oRawResponse.responseText; } try { // Convert to JSON object if it's a string if(lang.isString(oFullResponse)) { // Check for YUI JSON Util if(lang.JSON) { oFullResponse = lang.JSON.parse(oFullResponse); } // Look for JSON parsers using an API similar to json2.js else if(window.JSON && JSON.parse) { oFullResponse = JSON.parse(oFullResponse); } // Look for JSON parsers using an API similar to json.js else if(oFullResponse.parseJSON) { oFullResponse = oFullResponse.parseJSON(); } // No JSON lib found so parse the string else { // Trim leading spaces while (oFullResponse.length > 0 && (oFullResponse.charAt(0) != "{") && (oFullResponse.charAt(0) != "[")) { oFullResponse = oFullResponse.substring(1, oFullResponse.length); } if(oFullResponse.length > 0) { // Strip extraneous stuff at the end var objEnd = Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}")); oFullResponse = oFullResponse.substring(0,objEnd+1); // Turn the string into an object literal... // ...eval is necessary here oFullResponse = eval("(" + oFullResponse + ")"); } } } } catch(e) { } oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseJSONData(oRequest, oFullResponse); break; case DS.TYPE_HTMLTABLE: if(xhr && oRawResponse.responseText) { oFullResponse = oRawResponse.responseText; } oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseHTMLTableData(oRequest, oFullResponse); break; case DS.TYPE_XML: if(xhr && oRawResponse.responseXML) { oFullResponse = oRawResponse.responseXML; } oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseXMLData(oRequest, oFullResponse); break; case DS.TYPE_TEXT: if(xhr && lang.isString(oRawResponse.responseText)) { oFullResponse = oRawResponse.responseText; } oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseTextData(oRequest, oFullResponse); break; default: oFullResponse = this.doBeforeParseData(oRequest, oFullResponse, oCallback); oParsedResponse = this.parseData(oRequest, oFullResponse); break; } // Clean up for consistent signature oParsedResponse = oParsedResponse || {}; if(!oParsedResponse.results) { oParsedResponse.results = []; } if(!oParsedResponse.meta) { oParsedResponse.meta = {}; } // Success if(oParsedResponse && !oParsedResponse.error) { // Last chance to touch the raw response or the parsed response oParsedResponse = this.doBeforeCallback(oRequest, oFullResponse, oParsedResponse, oCallback); this.fireEvent("responseParseEvent", {request:oRequest, response:oParsedResponse, callback:oCallback, caller:oCaller}); // Cache the response this.addToCache(oRequest, oParsedResponse); } // Error else { // Be sure the error flag is on oParsedResponse.error = true; this.fireEvent("dataErrorEvent", {request:oRequest, response: oRawResponse, callback:oCallback, caller:oCaller, message:DS.ERROR_DATANULL}); } // Send the response back to the caller oParsedResponse.tId = tId; DS.issueCallback(oCallback,[oRequest,oParsedResponse],oParsedResponse.error,oCaller);},/** * Overridable method gives implementers access to the original full response * before the data gets parsed. Implementers should take care not to return an * unparsable or otherwise invalid response. * * @method doBeforeParseData * @param oRequest {Object} Request object. * @param oFullResponse {Object} The full response from the live database. * @param oCallback {Object} The callback object. * @return {Object} Full response for parsing. */doBeforeParseData : function(oRequest, oFullResponse, oCallback) { return oFullResponse;},/** * Overridable method gives implementers access to the original full response and * the parsed response (parsed against the given schema) before the data * is added to the cache (if applicable) and then sent back to callback function. * This is your chance to access the raw response and/or populate the parsed * response with any custom data. * * @method doBeforeCallback * @param oRequest {Object} Request object. * @param oFullResponse {Object} The full response from the live database. * @param oParsedResponse {Object} The parsed response to return to calling object. * @param oCallback {Object} The callback object. * @return {Object} Parsed response object. */doBeforeCallback : function(oRequest, oFullResponse, oParsedResponse, oCallback) { return oParsedResponse;},/** * Overridable method parses data of generic RESPONSE_TYPE into a response object. * * @method parseData * @param oRequest {Object} Request object. * @param oFullResponse {Object} The full Array from the live database. * @return {Object} Parsed response object with the following properties:<br> * - results {Array} Array of parsed data results<br> * - meta {Object} Object literal of meta values<br> * - error {Boolean} (optional) True if there was an error<br> */parseData : function(oRequest, oFullResponse) { if(lang.isValue(oFullResponse)) { var oParsedResponse = {results:oFullResponse,meta:{}}; return oParsedResponse; } return null;},/** * Overridable method parses Array data into a response object. * * @method parseArrayData * @param oRequest {Object} Request object. * @param oFullResponse {Object} The full Array from the live database. * @return {Object} Parsed response object with the following properties:<br> * - results (Array) Array of parsed data results<br> * - error (Boolean) True if there was an error */parseArrayData : function(oRequest, oFullResponse) { if(lang.isArray(oFullResponse)) { var results = [], i, j, rec, field, data; // Parse for fields if(lang.isArray(this.responseSchema.fields)) { var fields = this.responseSchema.fields; for (i = fields.length - 1; i >= 0; --i) { if (typeof fields[i] !== 'object') { fields[i] = { key : fields[i] }; } } var parsers = {}, p; for (i = fields.length - 1; i >= 0; --i) { p = (typeof fields[i].parser === 'function' ? fields[i].parser : DS.Parser[fields[i].parser+'']) || fields[i].converter; if (p) { parsers[fields[i].key] = p; } } var arrType = lang.isArray(oFullResponse[0]); for(i=oFullResponse.length-1; i>-1; i--) { var oResult = {}; rec = oFullResponse[i]; if (typeof rec === 'object') { for(j=fields.length-1; j>-1; j--) { field = fields[j]; data = arrType ? rec[j] : rec[field.key]; if (parsers[field.key]) { data = parsers[field.key].call(this,data); } // Safety measure if(data === undefined) { data = null; } oResult[field.key] = data; } } else if (lang.isString(rec)) { for(j=fields.length-1; j>-1; j--) { field = fields[j]; data = rec; if (parsers[field.key]) { data = parsers[field.key].call(this,data); } // Safety measure if(data === undefined) { data = null; } oResult[field.key] = data; } } results[i] = oResult; } } // Return entire data set else { results = oFullResponse; } var oParsedResponse = {results:results}; return oParsedResponse; } return null;},/** * Overridable method parses plain text data into a response object. * * @method parseTextData * @param oRequest {Object} Request object. * @param oFullResponse {Object} The full text response from the live database. * @return {Object} Parsed response object with the following properties:<br> * - results (Array) Array of parsed data results<br> * - error (Boolean) True if there was an error */parseTextData : function(oRequest, oFullResponse) { if(lang.isString(oFullResponse)) { if(lang.isString(this.responseSchema.recordDelim) && lang.isString(this.responseSchema.fieldDelim)) { var oParsedResponse = {results:[]}; var recDelim = this.responseSchema.recordDelim; var fieldDelim = this.responseSchema.fieldDelim; if(oFullResponse.length > 0) { // Delete the last line delimiter at the end of the data if it exists var newLength = oFullResponse.length-recDelim.length; if(oFullResponse.substr(newLength) == recDelim) { oFullResponse = oFullResponse.substr(0, newLength); } if(oFullResponse.length > 0) { // Split along record delimiter to get an array of strings var recordsarray = oFullResponse.split(recDelim); // Cycle through each record for(var i = 0, len = recordsarray.length, recIdx = 0; i < len; ++i) { var bError = false, sRecord = recordsarray[i]; if (lang.isString(sRecord) && (sRecord.length > 0)) { // Split each record along field delimiter to get data var fielddataarray = recordsarray[i].split(fieldDelim); var oResult = {}; // Filter for fields data if(lang.isArray(this.responseSchema.fields)) { var fields = this.responseSchema.fields; for(var j=fields.length-1; j>-1; j--) { try { // Remove quotation marks from edges, if applicable var data = fielddataarray[j]; if (lang.isString(data)) { if(data.charAt(0) == "\"") { data = data.substr(1); } if(data.charAt(data.length-1) == "\"") { data = data.substr(0,data.length-1); } var field = fields[j]; var key = (lang.isValue(field.key)) ? field.key : field; // Backward compatibility if(!field.parser && field.converter) { field.parser = field.converter; } var parser = (typeof field.parser === 'function') ? field.parser : DS.Parser[field.parser+'']; if(parser) { data = parser.call(this, data); } // Safety measure if(data === undefined) { data = null; } oResult[key] = data; } else { bError = true; } } catch(e) { bError = true; } } } // No fields defined so pass along all data as an array else { oResult = fielddataarray; } if(!bError) { oParsedResponse.results[recIdx++] = oResult; } } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -