tvheadend/vendor/ext-3.4.1/docs/source/JsonReader.html
Adam Sutton bafcfff42d webui: restructure webui/extjs source files
I want to keep the 3rd-party packages away from the main source
where possible.
2013-06-03 17:11:01 +01:00

373 lines
17 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
<script type="text/javascript">
function highlight() {
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
}
</script>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js"><span id='Ext-data-JsonReader-method-constructor'><span id='Ext-data-JsonReader'>/**
</span></span> * @class Ext.data.JsonReader
* @extends Ext.data.DataReader
* &lt;p&gt;Data reader class to create an Array of {@link Ext.data.Record} objects
* from a JSON packet based on mappings in a provided {@link Ext.data.Record}
* constructor.&lt;/p&gt;
* &lt;p&gt;Example code:&lt;/p&gt;
* &lt;pre&gt;&lt;code&gt;
var myReader = new Ext.data.JsonReader({
// metadata configuration options:
{@link #idProperty}: 'id'
{@link #root}: 'rows',
{@link #totalProperty}: 'results',
{@link Ext.data.DataReader#messageProperty}: &quot;msg&quot; // The element within the response that provides a user-feedback message (optional)
// the fields config option will internally create an {@link Ext.data.Record}
// constructor that provides mapping for reading the record data objects
{@link Ext.data.DataReader#fields fields}: [
// map Record&amp;#39;s 'firstname' field to data object&amp;#39;s key of same name
{name: 'name', mapping: 'firstname'},
// map Record&amp;#39;s 'job' field to data object&amp;#39;s 'occupation' key
{name: 'job', mapping: 'occupation'}
]
});
&lt;/code&gt;&lt;/pre&gt;
* &lt;p&gt;This would consume a JSON data object of the form:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
{
results: 2000, // Reader&amp;#39;s configured {@link #totalProperty}
rows: [ // Reader&amp;#39;s configured {@link #root}
// record data objects:
{ {@link #idProperty id}: 1, firstname: 'Bill', occupation: 'Gardener' },
{ {@link #idProperty id}: 2, firstname: 'Ben' , occupation: 'Horticulturalist' },
...
]
}
&lt;/code&gt;&lt;/pre&gt;
* &lt;p&gt;&lt;b&gt;&lt;u&gt;Automatic configuration using metaData&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
* &lt;p&gt;It is possible to change a JsonReader's metadata at any time by including
* a &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt; property in the JSON data object. If the JSON data
* object has a &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt; property, a {@link Ext.data.Store Store}
* object using this Reader will reconfigure itself to use the newly provided
* field definition and fire its {@link Ext.data.Store#metachange metachange}
* event. The metachange event handler may interrogate the &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt;
* property to perform any configuration required.&lt;/p&gt;
* &lt;p&gt;Note that reconfiguring a Store potentially invalidates objects which may
* refer to Fields or Records which no longer exist.&lt;/p&gt;
* &lt;p&gt;To use this facility you would create the JsonReader like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
var myReader = new Ext.data.JsonReader();
&lt;/code&gt;&lt;/pre&gt;
* &lt;p&gt;The first data packet from the server would configure the reader by
* containing a &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt; property &lt;b&gt;and&lt;/b&gt; the data. For
* example, the JSON data object might take the form:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
{
metaData: {
&quot;{@link #idProperty}&quot;: &quot;id&quot;,
&quot;{@link #root}&quot;: &quot;rows&quot;,
&quot;{@link #totalProperty}&quot;: &quot;results&quot;
&quot;{@link #successProperty}&quot;: &quot;success&quot;,
&quot;{@link Ext.data.DataReader#fields fields}&quot;: [
{&quot;name&quot;: &quot;name&quot;},
{&quot;name&quot;: &quot;job&quot;, &quot;mapping&quot;: &quot;occupation&quot;}
],
// used by store to set its sortInfo
&quot;sortInfo&quot;:{
&quot;field&quot;: &quot;name&quot;,
&quot;direction&quot;: &quot;ASC&quot;
},
// {@link Ext.PagingToolbar paging data} (if applicable)
&quot;start&quot;: 0,
&quot;limit&quot;: 2,
// custom property
&quot;foo&quot;: &quot;bar&quot;
},
// Reader&amp;#39;s configured {@link #successProperty}
&quot;success&quot;: true,
// Reader&amp;#39;s configured {@link #totalProperty}
&quot;results&quot;: 2000,
// Reader&amp;#39;s configured {@link #root}
// (this data simulates 2 results {@link Ext.PagingToolbar per page})
&quot;rows&quot;: [ // &lt;b&gt;*Note:&lt;/b&gt; this must be an Array
{ &quot;id&quot;: 1, &quot;name&quot;: &quot;Bill&quot;, &quot;occupation&quot;: &quot;Gardener&quot; },
{ &quot;id&quot;: 2, &quot;name&quot;: &quot;Ben&quot;, &quot;occupation&quot;: &quot;Horticulturalist&quot; }
]
}
* &lt;/code&gt;&lt;/pre&gt;
* &lt;p&gt;The &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt; property in the JSON data object should contain:&lt;/p&gt;
* &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
* &lt;li&gt;any of the configuration options for this class&lt;/li&gt;
* &lt;li&gt;a &lt;b&gt;&lt;tt&gt;{@link Ext.data.Record#fields fields}&lt;/tt&gt;&lt;/b&gt; property which
* the JsonReader will use as an argument to the
* {@link Ext.data.Record#create data Record create method} in order to
* configure the layout of the Records it will produce.&lt;/li&gt;
* &lt;li&gt;a &lt;b&gt;&lt;tt&gt;{@link Ext.data.Store#sortInfo sortInfo}&lt;/tt&gt;&lt;/b&gt; property
* which the JsonReader will use to set the {@link Ext.data.Store}'s
* {@link Ext.data.Store#sortInfo sortInfo} property&lt;/li&gt;
* &lt;li&gt;any custom properties needed&lt;/li&gt;
* &lt;/ul&gt;&lt;/div&gt;
*
* @constructor
* Create a new JsonReader
* @param {Object} meta Metadata configuration options.
* @param {Array/Object} recordType
* &lt;p&gt;Either an Array of {@link Ext.data.Field Field} definition objects (which
* will be passed to {@link Ext.data.Record#create}, or a {@link Ext.data.Record Record}
* constructor created from {@link Ext.data.Record#create}.&lt;/p&gt;
*/
Ext.data.JsonReader = function(meta, recordType){
meta = meta || {};
<span id='Ext-data-JsonReader-cfg-idProperty'> /**
</span> * @cfg {String} idProperty [id] Name of the property within a row object
* that contains a record identifier value. Defaults to &lt;tt&gt;id&lt;/tt&gt;
*/
<span id='Ext-data-JsonReader-cfg-successProperty'> /**
</span> * @cfg {String} successProperty [success] Name of the property from which to
* retrieve the success attribute. Defaults to &lt;tt&gt;success&lt;/tt&gt;. See
* {@link Ext.data.DataProxy}.{@link Ext.data.DataProxy#exception exception}
* for additional information.
*/
<span id='Ext-data-JsonReader-cfg-totalProperty'> /**
</span> * @cfg {String} totalProperty [total] Name of the property from which to
* retrieve the total number of records in the dataset. This is only needed
* if the whole dataset is not passed in one go, but is being paged from
* the remote server. Defaults to &lt;tt&gt;total&lt;/tt&gt;.
*/
<span id='Ext-data-JsonReader-cfg-root'> /**
</span> * @cfg {String} root [undefined] &lt;b&gt;Required&lt;/b&gt;. The name of the property
* which contains the Array of row objects. Defaults to &lt;tt&gt;undefined&lt;/tt&gt;.
* An exception will be thrown if the root property is undefined. The data
* packet value for this property should be an empty array to clear the data
* or show no data.
*/
Ext.applyIf(meta, {
idProperty: 'id',
successProperty: 'success',
totalProperty: 'total'
});
Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
<span id='Ext-data-JsonReader-property-meta'> /**
</span> * This JsonReader's metadata as passed to the constructor, or as passed in
* the last data packet's &lt;b&gt;&lt;tt&gt;metaData&lt;/tt&gt;&lt;/b&gt; property.
* @type Mixed
* @property meta
*/
<span id='Ext-data-JsonReader-method-read'> /**
</span> * This method is only used by a DataProxy which has retrieved data from a remote server.
* @param {Object} response The XHR object which contains the JSON data in its responseText.
* @return {Object} data A data block which is used by an Ext.data.Store object as
* a cache of Ext.data.Records.
*/
read : function(response){
var json = response.responseText;
var o = Ext.decode(json);
if(!o) {
throw {message: 'JsonReader.read: Json object not found'};
}
return this.readRecords(o);
},
/*
* TODO: refactor code between JsonReader#readRecords, #readResponse into 1 method.
* there's ugly duplication going on due to maintaining backwards compat. with 2.0. It's time to do this.
*/
<span id='Ext-data-JsonReader-method-readResponse'> /**
</span> * Decode a JSON response from server.
* @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
* @param {Object} response The XHR object returned through an Ajax server request.
* @return {Response} A {@link Ext.data.Response Response} object containing the data response, and also status information.
*/
readResponse : function(action, response) {
var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
if(!o) {
throw new Ext.data.JsonReader.Error('response');
}
var root = this.getRoot(o),
success = this.getSuccess(o);
if (success &amp;&amp; action === Ext.data.Api.actions.create) {
var def = Ext.isDefined(root);
if (def &amp;&amp; Ext.isEmpty(root)) {
throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
}
else if (!def) {
throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
}
}
// instantiate response object
var res = new Ext.data.Response({
action: action,
success: success,
data: (root) ? this.extractData(root, false) : [],
message: this.getMessage(o),
raw: o
});
// blow up if no successProperty
if (Ext.isEmpty(res.success)) {
throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
}
return res;
},
<span id='Ext-data-JsonReader-method-readRecords'> /**
</span> * Create a data block containing Ext.data.Records from a JSON object.
* @param {Object} o An object which contains an Array of row objects in the property specified
* in the config as 'root, and optionally a property, specified in the config as 'totalProperty'
* which contains the total size of the dataset.
* @return {Object} data A data block which is used by an Ext.data.Store object as
* a cache of Ext.data.Records.
*/
readRecords : function(o){
<span id='Ext-data-JsonReader-property-jsonData'> /**
</span> * After any data loads, the raw JSON data is available for further custom processing. If no data is
* loaded or there is a load exception this property will be undefined.
* @type Object
*/
this.jsonData = o;
if(o.metaData){
this.onMetaChange(o.metaData);
}
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length, v;
var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
if(s.totalProperty){
v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(s.successProperty){
v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}
// TODO return Ext.data.Response instance instead. @see #readResponse
return {
success : success,
records : this.extractData(root, true), // &lt;-- true to return [Ext.data.Record]
totalRecords : totalRecords
};
},
// private
buildExtractors : function() {
if(this.ef){
return;
}
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length;
if(s.totalProperty) {
this.getTotal = this.createAccessor(s.totalProperty);
}
if(s.successProperty) {
this.getSuccess = this.createAccessor(s.successProperty);
}
if (s.messageProperty) {
this.getMessage = this.createAccessor(s.messageProperty);
}
this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
if (s.id || s.idProperty) {
var g = this.createAccessor(s.id || s.idProperty);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === '') ? null : r;
};
} else {
this.getId = function(){return null;};
}
var ef = [];
for(var i = 0; i &lt; fl; i++){
f = fi[i];
var map = (f.mapping !== undefined &amp;&amp; f.mapping !== null) ? f.mapping : f.name;
ef.push(this.createAccessor(map));
}
this.ef = ef;
},
<span id='global-method-simpleAccess'> /**
</span> * @ignore
* TODO This isn't used anywhere?? Don't we want to use this where possible instead of complex #createAccessor?
*/
simpleAccess : function(obj, subsc) {
return obj[subsc];
},
<span id='global-property-createAccessor'> /**
</span> * @ignore
*/
createAccessor : function(){
var re = /[\[\.]/;
return function(expr) {
if(Ext.isEmpty(expr)){
return Ext.emptyFn;
}
if(Ext.isFunction(expr)){
return expr;
}
var i = String(expr).search(re);
if(i &gt;= 0){
return new Function('obj', 'return obj' + (i &gt; 0 ? '.' : '') + expr);
}
return function(obj){
return obj[expr];
};
};
}(),
<span id='Ext-data-JsonReader-method-extractValues'> /**
</span> * type-casts a single row of raw-data from server
* @param {Object} data
* @param {Array} items
* @param {Integer} len
* @private
*/
extractValues : function(data, items, len) {
var f, values = {};
for(var j = 0; j &lt; len; j++){
f = items[j];
var v = this.ef[j](data);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
}
return values;
}
});
<span id='Ext-data-JsonReader-Error'>/**
</span> * @class Ext.data.JsonReader.Error
* Error class for JsonReader
*/
Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
<span id='Ext-data-JsonReader-Error-method-constructor'> constructor : function(message, arg) {
</span> this.arg = arg;
Ext.Error.call(this, message);
},
<span id='Ext-data-JsonReader-Error-property-name'> name : 'Ext.data.JsonReader'
</span>});
Ext.apply(Ext.data.JsonReader.Error.prototype, {
lang: {
'response': 'An error occurred while json-decoding your server response',
'successProperty-response': 'Could not locate your &quot;successProperty&quot; in your server response. Please review your JsonReader config to ensure the config-property &quot;successProperty&quot; matches the property in your server-response. See the JsonReader docs.',
'root-undefined-config': 'Your JsonReader was configured without a &quot;root&quot; property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.',
'idProperty-undefined' : 'Your JsonReader was configured without an &quot;idProperty&quot; Please review your JsonReader configuration and ensure the &quot;idProperty&quot; is set (e.g.: &quot;id&quot;). See the JsonReader docs.',
'root-empty': 'Data was expected to be returned by the server in the &quot;root&quot; property of the response. Please review your JsonReader configuration to ensure the &quot;root&quot; property matches that returned in the server-response. See JsonReader docs.'
}
});
</pre>
</body>
</html>