/** * @author Ed Spencer * * Base Writer class used by most subclasses of {@link Ext.data.proxy.Server}. This class is * responsible for taking a set of {@link Ext.data.Operation} objects and a {@link Ext.data.Request} * object and modifying that request based on the Operations. * * For example a Ext.data.writer.Json would format the Operations and their {@link Ext.data.Model} * instances based on the config options passed to the JsonWriter's constructor. * * Writers are not needed for any kind of local storage - whether via a * {@link Ext.data.proxy.WebStorage Web Storage proxy} (see {@link Ext.data.proxy.LocalStorage localStorage}) * or just in memory via a {@link Ext.data.proxy.Memory MemoryProxy}. */ Ext.define('Ext.data.writer.Writer', { alias: 'writer.base', alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'], config: { /** * @cfg {Boolean} writeAllFields `true` to write all fields from the record to the server. If set to `false` it * will only send the fields that were modified. Note that any fields that have * {@link Ext.data.Field#persist} set to false will still be ignored. */ writeAllFields: true, /** * @cfg {String} nameProperty This property is used to read the key for each value that will be sent to the server. * For example: * * Ext.define('Person', { * extend: 'Ext.data.Model', * fields: [{ * name: 'first', * mapping: 'firstName' * }, { * name: 'last', * mapping: 'lastName' * }, { * name: 'age' * }] * }); * * new Ext.data.writer.Writer({ * writeAllFields: true, * nameProperty: 'mapping' * }); * * The following data will be sent to the server: * * { * firstName: 'first name value', * lastName: 'last name value', * age: 1 * } * * If the value is not present, the field name will always be used. */ nameProperty: 'name' }, /** * Creates new Writer. * @param {Object} config (optional) Config object. */ constructor: function(config) { this.initConfig(config); }, /** * Prepares a Proxy's Ext.data.Request object. * @param {Ext.data.Request} request The request object. * @return {Ext.data.Request} The modified request object. */ write: function(request) { var operation = request.getOperation(), records = operation.getRecords() || [], len = records.length, i = 0, data = []; for (; i < len; i++) { data.push(this.getRecordData(records[i])); } return this.writeRecords(request, data); }, writeDate: function(field, date) { if (!date) { return null; } var dateFormat = field.getDateFormat() || 'timestamp'; switch (dateFormat) { case 'timestamp': return date.getTime()/1000; case 'time': return date.getTime(); default: return Ext.Date.format(date, dateFormat); } }, /** * Formats the data for each record before sending it to the server. This * method should be overridden to format the data in a way that differs from the default. * @param {Object} record The record that we are writing to the server. * @return {Object} An object literal of name/value keys to be written to the server. * By default this method returns the data property on the record. */ getRecordData: function(record) { var isPhantom = record.phantom === true, writeAll = this.getWriteAllFields() || isPhantom, nameProperty = this.getNameProperty(), fields = record.getFields(), data = {}, changes, name, field, key, value; if (writeAll) { fields.each(function(field) { if (field.getPersist()) { name = field.config[nameProperty] || field.getName(); value = record.get(field.getName()); if (field.getType().type == 'date') { value = this.writeDate(field, value); } data[name] = value; } }, this); } else { // Only write the changes changes = record.getChanges(); for (key in changes) { if (changes.hasOwnProperty(key)) { field = fields.get(key); if (field.getPersist()) { name = field.config[nameProperty] || field.getName(); value = changes[key]; if (field.getType().type == 'date') { value = this.writeDate(field, value); } data[name] = value; } } } if (!isPhantom) { // always include the id for non phantoms data[record.getIdProperty()] = record.getId(); } } return data; } // Convert old properties in data into a config object // <deprecated product=touch since=2.0> ,onClassExtended: function(cls, data, hooks) { var Component = this, defaultConfig = Component.prototype.config, config = data.config || {}, key; for (key in defaultConfig) { if (key in data) { config[key] = data[key]; delete data[key]; // <debug warn> Ext.Logger.deprecate(key + ' is deprecated as a property directly on the Writer prototype. ' + 'Please put it inside the config object.'); // </debug> } } data.config = config; } // </deprecated> });