/javascripts/lib/docs/source/Record.html
HTML | 426 lines | 421 code | 5 blank | 0 comment | 0 complexity | 8a53aeb8c5d4fa9b3282b022965d57df MD5 | raw file
Possible License(s): GPL-3.0
1<html> 2<head> 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 4 <title>The source code</title> 5 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> 6 <script type="text/javascript" src="../resources/prettify/prettify.js"></script> 7</head> 8<body onload="prettyPrint();"> 9 <pre class="prettyprint lang-js">/*! 10 * Ext JS Library 3.2.1 11 * Copyright(c) 2006-2010 Ext JS, Inc. 12 * licensing@extjs.com 13 * http://www.extjs.com/license 14 */ 15<div id="cls-Ext.data.Record"></div>/** 16 * @class Ext.data.Record 17 * <p>Instances of this class encapsulate both Record <em>definition</em> information, and Record 18 * <em>value</em> information for use in {@link Ext.data.Store} objects, or any code which needs 19 * to access Records cached in an {@link Ext.data.Store} object.</p> 20 * <p>Constructors for this class are generated by passing an Array of field definition objects to {@link #create}. 21 * Instances are usually only created by {@link Ext.data.Reader} implementations when processing unformatted data 22 * objects.</p> 23 * <p>Note that an instance of a Record class may only belong to one {@link Ext.data.Store Store} at a time. 24 * In order to copy data from one Store to another, use the {@link #copy} method to create an exact 25 * copy of the Record, and insert the new instance into the other Store.</p> 26 * <p>When serializing a Record for submission to the server, be aware that it contains many private 27 * properties, and also a reference to its owning Store which in turn holds references to its Records. 28 * This means that a whole Record may not be encoded using {@link Ext.util.JSON.encode}. Instead, use the 29 * <code>{@link #data}</code> and <code>{@link #id}</code> properties.</p> 30 * <p>Record objects generated by this constructor inherit all the methods of Ext.data.Record listed below.</p> 31 * @constructor 32 * <p>This constructor should not be used to create Record objects. Instead, use {@link #create} to 33 * generate a subclass of Ext.data.Record configured with information about its constituent fields.<p> 34 * <p><b>The generated constructor has the same signature as this constructor.</b></p> 35 * @param {Object} data (Optional) An object, the properties of which provide values for the new Record's 36 * fields. If not specified the <code>{@link Ext.data.Field#defaultValue defaultValue}</code> 37 * for each field will be assigned. 38 * @param {Object} id (Optional) The id of the Record. The id is used by the 39 * {@link Ext.data.Store} object which owns the Record to index its collection 40 * of Records (therefore this id should be unique within each store). If an 41 * <code>id</code> is not specified a <b><code>{@link #phantom}</code></b> 42 * Record will be created with an {@link #Record.id automatically generated id}. 43 */ 44Ext.data.Record = function(data, id){ 45 // if no id, call the auto id method 46 this.id = (id || id === 0) ? id : Ext.data.Record.id(this); 47 this.data = data || {}; 48}; 49 50<div id="method-Ext.data.Record-create"></div>/** 51 * Generate a constructor for a specific Record layout. 52 * @param {Array} o An Array of <b>{@link Ext.data.Field Field}</b> definition objects. 53 * The constructor generated by this method may be used to create new Record instances. The data 54 * object must contain properties named after the {@link Ext.data.Field field} 55 * <b><tt>{@link Ext.data.Field#name}s</tt></b>. Example usage:<pre><code> 56// create a Record constructor from a description of the fields 57var TopicRecord = Ext.data.Record.create([ // creates a subclass of Ext.data.Record 58 {{@link Ext.data.Field#name name}: 'title', {@link Ext.data.Field#mapping mapping}: 'topic_title'}, 59 {name: 'author', mapping: 'username', allowBlank: false}, 60 {name: 'totalPosts', mapping: 'topic_replies', type: 'int'}, 61 {name: 'lastPost', mapping: 'post_time', type: 'date'}, 62 {name: 'lastPoster', mapping: 'user2'}, 63 {name: 'excerpt', mapping: 'post_text', allowBlank: false}, 64 // In the simplest case, if no properties other than <tt>name</tt> are required, 65 // a field definition may consist of just a String for the field name. 66 'signature' 67]); 68 69// create Record instance 70var myNewRecord = new TopicRecord( 71 { 72 title: 'Do my job please', 73 author: 'noobie', 74 totalPosts: 1, 75 lastPost: new Date(), 76 lastPoster: 'Animal', 77 excerpt: 'No way dude!', 78 signature: '' 79 }, 80 id // optionally specify the id of the record otherwise {@link #Record.id one is auto-assigned} 81); 82myStore.{@link Ext.data.Store#add add}(myNewRecord); 83</code></pre> 84 * @method create 85 * @return {Function} A constructor which is used to create new Records according 86 * to the definition. The constructor has the same signature as {@link #Record}. 87 * @static 88 */ 89Ext.data.Record.create = function(o){ 90 var f = Ext.extend(Ext.data.Record, {}); 91 var p = f.prototype; 92 p.fields = new Ext.util.MixedCollection(false, function(field){ 93 return field.name; 94 }); 95 for(var i = 0, len = o.length; i < len; i++){ 96 p.fields.add(new Ext.data.Field(o[i])); 97 } 98 f.getField = function(name){ 99 return p.fields.get(name); 100 }; 101 return f; 102}; 103 104Ext.data.Record.PREFIX = 'ext-record'; 105Ext.data.Record.AUTO_ID = 1; 106Ext.data.Record.EDIT = 'edit'; 107Ext.data.Record.REJECT = 'reject'; 108Ext.data.Record.COMMIT = 'commit'; 109 110 111<div id="method-Ext.data.Record-Record.id"></div>/** 112 * Generates a sequential id. This method is typically called when a record is {@link #create}d 113 * and {@link #Record no id has been specified}. The returned id takes the form: 114 * <tt>{PREFIX}-{AUTO_ID}</tt>.<div class="mdetail-params"><ul> 115 * <li><b><tt>PREFIX</tt></b> : String<p class="sub-desc"><tt>Ext.data.Record.PREFIX</tt> 116 * (defaults to <tt>'ext-record'</tt>)</p></li> 117 * <li><b><tt>AUTO_ID</tt></b> : String<p class="sub-desc"><tt>Ext.data.Record.AUTO_ID</tt> 118 * (defaults to <tt>1</tt> initially)</p></li> 119 * </ul></div> 120 * @param {Record} rec The record being created. The record does not exist, it's a {@link #phantom}. 121 * @return {String} auto-generated string id, <tt>"ext-record-i++'</tt>; 122 */ 123Ext.data.Record.id = function(rec) { 124 rec.phantom = true; 125 return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join(''); 126}; 127 128Ext.data.Record.prototype = { 129 <div id="prop-Ext.data.Record-fields"></div>/** 130 * <p><b>This property is stored in the Record definition's <u>prototype</u></b></p> 131 * A MixedCollection containing the defined {@link Ext.data.Field Field}s for this Record. Read-only. 132 * @property fields 133 * @type Ext.util.MixedCollection 134 */ 135 <div id="prop-Ext.data.Record-data"></div>/** 136 * An object hash representing the data for this Record. Every field name in the Record definition 137 * is represented by a property of that name in this object. Note that unless you specified a field 138 * with {@link Ext.data.Field#name name} "id" in the Record definition, this will <b>not</b> contain 139 * an <tt>id</tt> property. 140 * @property data 141 * @type {Object} 142 */ 143 <div id="prop-Ext.data.Record-id"></div>/** 144 * The unique ID of the Record {@link #Record as specified at construction time}. 145 * @property id 146 * @type {Object} 147 */ 148 <div id="prop-Ext.data.Record-node"></div>/** 149 * <p><b>Only present if this Record was created by an {@link Ext.data.XmlReader XmlReader}</b>.</p> 150 * <p>The XML element which was the source of the data for this Record.</p> 151 * @property node 152 * @type {XMLElement} 153 */ 154 <div id="prop-Ext.data.Record-json"></div>/** 155 * <p><b>Only present if this Record was created by an {@link Ext.data.ArrayReader ArrayReader} or a {@link Ext.data.JsonReader JsonReader}</b>.</p> 156 * <p>The Array or object which was the source of the data for this Record.</p> 157 * @property json 158 * @type {Array|Object} 159 */ 160 <div id="prop-Ext.data.Record-dirty"></div>/** 161 * Readonly flag - true if this Record has been modified. 162 * @type Boolean 163 */ 164 dirty : false, 165 editing : false, 166 error : null, 167 <div id="prop-Ext.data.Record-modified"></div>/** 168 * This object contains a key and value storing the original values of all modified 169 * fields or is null if no fields have been modified. 170 * @property modified 171 * @type {Object} 172 */ 173 modified : null, 174 <div id="prop-Ext.data.Record-phantom"></div>/** 175 * <tt>true</tt> when the record does not yet exist in a server-side database (see 176 * {@link #markDirty}). Any record which has a real database pk set as its id property 177 * is NOT a phantom -- it's real. 178 * @property phantom 179 * @type {Boolean} 180 */ 181 phantom : false, 182 183 // private 184 join : function(store){ 185 <div id="prop-Ext.data.Record-store"></div>/** 186 * The {@link Ext.data.Store} to which this Record belongs. 187 * @property store 188 * @type {Ext.data.Store} 189 */ 190 this.store = store; 191 }, 192 193 <div id="method-Ext.data.Record-set"></div>/** 194 * Set the {@link Ext.data.Field#name named field} to the specified value. For example: 195 * <pre><code> 196// record has a field named 'firstname' 197var Employee = Ext.data.Record.{@link #create}([ 198 {name: 'firstname'}, 199 ... 200]); 201 202// update the 2nd record in the store: 203var rec = myStore.{@link Ext.data.Store#getAt getAt}(1); 204 205// set the value (shows dirty flag): 206rec.set('firstname', 'Betty'); 207 208// commit the change (removes dirty flag): 209rec.{@link #commit}(); 210 211// update the record in the store, bypass setting dirty flag, 212// and do not store the change in the {@link Ext.data.Store#getModifiedRecords modified records} 213rec.{@link #data}['firstname'] = 'Wilma'; // updates record, but not the view 214rec.{@link #commit}(); // updates the view 215 * </code></pre> 216 * <b>Notes</b>:<div class="mdetail-params"><ul> 217 * <li>If the store has a writer and <code>autoSave=true</code>, each set() 218 * will execute an XHR to the server.</li> 219 * <li>Use <code>{@link #beginEdit}</code> to prevent the store's <code>update</code> 220 * event firing while using set().</li> 221 * <li>Use <code>{@link #endEdit}</code> to have the store's <code>update</code> 222 * event fire.</li> 223 * </ul></div> 224 * @param {String} name The {@link Ext.data.Field#name name of the field} to set. 225 * @param {String/Object/Array} value The value to set the field to. 226 */ 227 set : function(name, value){ 228 var encode = Ext.isPrimitive(value) ? String : Ext.encode; 229 if(encode(this.data[name]) == encode(value)) { 230 return; 231 } 232 this.dirty = true; 233 if(!this.modified){ 234 this.modified = {}; 235 } 236 if(this.modified[name] === undefined){ 237 this.modified[name] = this.data[name]; 238 } 239 this.data[name] = value; 240 if(!this.editing){ 241 this.afterEdit(); 242 } 243 }, 244 245 // private 246 afterEdit : function(){ 247 if (this.store != undefined && typeof this.store.afterEdit == "function") { 248 this.store.afterEdit(this); 249 } 250 }, 251 252 // private 253 afterReject : function(){ 254 if(this.store){ 255 this.store.afterReject(this); 256 } 257 }, 258 259 // private 260 afterCommit : function(){ 261 if(this.store){ 262 this.store.afterCommit(this); 263 } 264 }, 265 266 <div id="method-Ext.data.Record-get"></div>/** 267 * Get the value of the {@link Ext.data.Field#name named field}. 268 * @param {String} name The {@link Ext.data.Field#name name of the field} to get the value of. 269 * @return {Object} The value of the field. 270 */ 271 get : function(name){ 272 return this.data[name]; 273 }, 274 275 <div id="method-Ext.data.Record-beginEdit"></div>/** 276 * Begin an edit. While in edit mode, no events (e.g.. the <code>update</code> event) 277 * are relayed to the containing store. 278 * See also: <code>{@link #endEdit}</code> and <code>{@link #cancelEdit}</code>. 279 */ 280 beginEdit : function(){ 281 this.editing = true; 282 this.modified = this.modified || {}; 283 }, 284 285 <div id="method-Ext.data.Record-cancelEdit"></div>/** 286 * Cancels all changes made in the current edit operation. 287 */ 288 cancelEdit : function(){ 289 this.editing = false; 290 delete this.modified; 291 }, 292 293 <div id="method-Ext.data.Record-endEdit"></div>/** 294 * End an edit. If any data was modified, the containing store is notified 295 * (ie, the store's <code>update</code> event will fire). 296 */ 297 endEdit : function(){ 298 this.editing = false; 299 if(this.dirty){ 300 this.afterEdit(); 301 } 302 }, 303 304 <div id="method-Ext.data.Record-reject"></div>/** 305 * Usually called by the {@link Ext.data.Store} which owns the Record. 306 * Rejects all changes made to the Record since either creation, or the last commit operation. 307 * Modified fields are reverted to their original values. 308 * <p>Developers should subscribe to the {@link Ext.data.Store#update} event 309 * to have their code notified of reject operations.</p> 310 * @param {Boolean} silent (optional) True to skip notification of the owning 311 * store of the change (defaults to false) 312 */ 313 reject : function(silent){ 314 var m = this.modified; 315 for(var n in m){ 316 if(typeof m[n] != "function"){ 317 this.data[n] = m[n]; 318 } 319 } 320 this.dirty = false; 321 delete this.modified; 322 this.editing = false; 323 if(silent !== true){ 324 this.afterReject(); 325 } 326 }, 327 328 <div id="method-Ext.data.Record-commit"></div>/** 329 * Usually called by the {@link Ext.data.Store} which owns the Record. 330 * Commits all changes made to the Record since either creation, or the last commit operation. 331 * <p>Developers should subscribe to the {@link Ext.data.Store#update} event 332 * to have their code notified of commit operations.</p> 333 * @param {Boolean} silent (optional) True to skip notification of the owning 334 * store of the change (defaults to false) 335 */ 336 commit : function(silent){ 337 this.dirty = false; 338 delete this.modified; 339 this.editing = false; 340 if(silent !== true){ 341 this.afterCommit(); 342 } 343 }, 344 345 <div id="method-Ext.data.Record-getChanges"></div>/** 346 * Gets a hash of only the fields that have been modified since this Record was created or commited. 347 * @return Object 348 */ 349 getChanges : function(){ 350 var m = this.modified, cs = {}; 351 for(var n in m){ 352 if(m.hasOwnProperty(n)){ 353 cs[n] = this.data[n]; 354 } 355 } 356 return cs; 357 }, 358 359 // private 360 hasError : function(){ 361 return this.error !== null; 362 }, 363 364 // private 365 clearError : function(){ 366 this.error = null; 367 }, 368 369 <div id="method-Ext.data.Record-copy"></div>/** 370 * Creates a copy (clone) of this Record. 371 * @param {String} id (optional) A new Record id, defaults to the id 372 * of the record being copied. See <code>{@link #id}</code>. 373 * To generate a phantom record with a new id use:<pre><code> 374var rec = record.copy(); // clone the record 375Ext.data.Record.id(rec); // automatically generate a unique sequential id 376 * </code></pre> 377 * @return {Record} 378 */ 379 copy : function(newId) { 380 return new this.constructor(Ext.apply({}, this.data), newId || this.id); 381 }, 382 383 <div id="method-Ext.data.Record-isModified"></div>/** 384 * Returns <tt>true</tt> if the passed field name has been <code>{@link #modified}</code> 385 * since the load or last commit. 386 * @param {String} fieldName {@link Ext.data.Field.{@link Ext.data.Field#name} 387 * @return {Boolean} 388 */ 389 isModified : function(fieldName){ 390 return !!(this.modified && this.modified.hasOwnProperty(fieldName)); 391 }, 392 393 <div id="method-Ext.data.Record-isValid"></div>/** 394 * By default returns <tt>false</tt> if any {@link Ext.data.Field field} within the 395 * record configured with <tt>{@link Ext.data.Field#allowBlank} = false</tt> returns 396 * <tt>true</tt> from an {@link Ext}.{@link Ext#isEmpty isempty} test. 397 * @return {Boolean} 398 */ 399 isValid : function() { 400 return this.fields.find(function(f) { 401 return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false; 402 },this) ? false : true; 403 }, 404 405 <div id="method-Ext.data.Record-markDirty"></div>/** 406 * <p>Marks this <b>Record</b> as <code>{@link #dirty}</code>. This method 407 * is used interally when adding <code>{@link #phantom}</code> records to a 408 * {@link Ext.data.Store#writer writer enabled store}.</p> 409 * <br><p>Marking a record <code>{@link #dirty}</code> causes the phantom to 410 * be returned by {@link Ext.data.Store#getModifiedRecords} where it will 411 * have a create action composed for it during {@link Ext.data.Store#save store save} 412 * operations.</p> 413 */ 414 markDirty : function(){ 415 this.dirty = true; 416 if(!this.modified){ 417 this.modified = {}; 418 } 419 this.fields.each(function(f) { 420 this.modified[f.name] = this.data[f.name]; 421 },this); 422 } 423}; 424</pre> 425</body> 426</html>