Skip to content

Instantly share code, notes, and snippets.

@JohanVandeplas
Created March 11, 2012 16:53
Show Gist options
  • Save JohanVandeplas/2017112 to your computer and use it in GitHub Desktop.
Save JohanVandeplas/2017112 to your computer and use it in GitHub Desktop.
Snippet from the Sencha Touch 2.0 framework
/**
* @class Ext.data.NodeInterface
* This class is meant to be used as a set of methods that are applied to the prototype of a
* Record to decorate it with a Node API. This means that models used in conjunction with a tree
* will have all of the tree related methods available on the model. In general this class will
* not be used directly by the developer. This class also creates extra fields on the model if
* they do not exist, to help maintain the tree state and UI. These fields are:
* <ul>
* <li>parentId</li>
* <li>index</li>
* <li>depth</li>
* <li>expanded</li>
* <li>expandable</li>
* <li>checked</li>
* <li>leaf</li>
* <li>cls</li>
* <li>iconCls</li>
* <li>root</li>
* <li>isLast</li>
* <li>isFirst</li>
* <li>allowDrop</li>
* <li>allowDrag</li>
* <li>loaded</li>
* <li>loading</li>
* <li>href</li>
* <li>hrefTarget</li>
* <li>qtip</li>
* <li>qtitle</li>
* </ul>
*
*/
Ext.define('Ext.data.NodeInterface', {
requires: ['Ext.data.Field', 'Ext.data.ModelManager'],
alternateClassName: 'Ext.data.Node',
/**
* @property nextSibling
* A reference to this node's next sibling node. `null` if this node does not have a next sibling.
*/
/**
* @property previousSibling
* A reference to this node's previous sibling node. `null` if this node does not have a previous sibling.
*/
/**
* @property parentNode
* A reference to this node's parent node. `null` if this node is the root node.
*/
/**
* @property lastChild
* A reference to this node's last child node. `null` if this node has no children.
*/
/**
* @property firstChild
* A reference to this node's first child node. `null` if this node has no children.
*/
/**
* @property childNodes
* An array of this nodes children. Array will be empty if this node has no chidren.
*/
statics: {
/**
* This method allows you to decorate a Record's prototype to implement the NodeInterface.
* This adds a set of methods, new events, new properties and new fields on every Record
* with the same Model as the passed Record.
* @param {Ext.data.Model} record The Record you want to decorate the prototype of.
* @static
*/
decorate: function(record) {
if (!record.isNode) {
// Apply the methods and fields to the prototype
var mgr = Ext.data.ModelManager,
modelName = record.modelName,
modelClass = mgr.getModel(modelName),
newFields = [],
i, newField, len;
// Start by adding the NodeInterface methods to the Model's prototype
modelClass.override(this.getPrototypeBody());
newFields = this.applyFields(modelClass, [
{name: 'parentId', type: 'string', defaultValue: null},
{name: 'index', type: 'int', defaultValue: 0},
{name: 'depth', type: 'int', defaultValue: 0, persist: false},
{name: 'expanded', type: 'bool', defaultValue: false, persist: false},
{name: 'expandable', type: 'bool', defaultValue: true, persist: false},
{name: 'checked', type: 'auto', defaultValue: null},
{name: 'leaf', type: 'bool', defaultValue: false, persist: false},
{name: 'cls', type: 'string', defaultValue: null, persist: false},
{name: 'iconCls', type: 'string', defaultValue: null, persist: false},
{name: 'root', type: 'boolean', defaultValue: false, persist: false},
{name: 'isLast', type: 'boolean', defaultValue: false, persist: false},
{name: 'isFirst', type: 'boolean', defaultValue: false, persist: false},
{name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false},
{name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false},
{name: 'loaded', type: 'boolean', defaultValue: false, persist: false},
{name: 'loading', type: 'boolean', defaultValue: false, persist: false},
{name: 'href', type: 'string', defaultValue: null, persist: false},
{name: 'hrefTarget', type: 'string', defaultValue: null, persist: false},
{name: 'qtip', type: 'string', defaultValue: null, persist: false},
{name: 'qtitle', type: 'string', defaultValue: null, persist: false}
]);
len = newFields.length;
// We set a dirty flag on the fields collection of the model. Any reader that
// will read in data for this model will update their extractor functions.
modelClass.getFields().isDirty = true;
// Set default values
for (i = 0; i < len; ++i) {
newField = newFields[i];
if (record.get(newField.getName()) === undefined) {
record.data[newField.getName()] = newField.getDefaultValue();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment