Created
July 21, 2011 19:07
-
-
Save lsmith/1097943 to your computer and use it in GitHub Desktop.
Make Y.DataTable instantiable, and an extension point for feature extension classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Right now, Y.DataTable is only a namespace. But I want to be able to say new Y.DataTable({...}); | |
// We can do it. We have the technology. | |
// Step 1. Capture all the properties of the Y.DataTable namespace | |
// Y.merge creates a shallow copy of an object, and since Y.DataTable is just a namespace object, | |
// this works like a champ. You could now say new Stuff.Base({...}) to create a DataTable.Base | |
// instance. | |
var Stuff = Y.merge(Y.DataTable); | |
// Step 2. Replace the Y.DataTable namespace with a working DataTable.Base subclass | |
// This class will be the target of DataTable feature class extensions, but for now, start | |
// from scratch. Note it's important that this be a DataTable.Base subclass rather than | |
// DataTable.Base itself because features will be mixed into it and we want to preserve | |
// the sanctity of DataTable.Base as the featureless base class for other DataTable flavors. | |
Y.DataTable = Y.Base.create('datatable', Y.DataTable.Base, []); | |
// Step 3. Add the formerly namespaced stuff back onto Y.DataTable | |
// Because Y.DataTable is now a class, there is potential for name collision between static | |
// features and namespaced functionality. I'm hopeful that this won't be an issue in practice. | |
Y.mix(Y.DataTable, Stuff); | |
// Step 3.5. Y.DataTable and Y.DataTable.Base should each be instantiable | |
var baseTable = new Y.DataTable.Base({ /* works like before */ }); | |
var table = new Y.DataTable({ /* also works now, but here comes the magic... */ }); | |
// Step 4. Add a Y.DataTable.Features namespace for mix-and-match class assembly from DataTable.Base | |
// This is to support creating a DataTable.Base subclass with specific features, in case the | |
// "community" Y.DataTable get's a conflicting/undesirable feature. | |
Y.namespace('DataTable.Features'); | |
// Step 5. Create a DataTable feature as a class extension, and store | |
// the feature in the new namespace | |
YUI.add('gallery-datatable-awesomesauce', function (Y) { | |
function AwesomeSauce() {} | |
// Additional Y.DataTable.prototype properties, supplied by this feature | |
AwesomeSauce.prototype = { | |
howHot: function () { | |
return (this.get('hotness') > 50) ? "Hellz yeah!" : "Meh"; | |
} | |
}; | |
AwesomeSauce.ATTRS = { | |
hotness: { | |
value: 5, | |
validator: Y.Lang.isNumber | |
} | |
}; | |
Y.DataTable.Features.AwesomeSauce = AwesomeSauce; | |
// Step 6. (optional) Mix the feature into Y.DataTable if it doesn't alter | |
// default behavior. In general, try to make extensions in a way such that | |
// feature related behavior is opt-in. | |
Y.Base.mix(Y.DataTable, [Y.DataTable.Features.AwesomeSauce]); | |
}, '0.1', { requires: ['datatable-base'] }); | |
// Grand finale. By use()ing the feature extension, new Y.DataTable instances | |
// will support those features | |
YUI().use('gallery-datatable-awesomesauce', function (Y) { | |
var table = new Y.DataTable({ | |
recordset: [ ... ], | |
columnset: [ ... ], | |
hotness: 100 | |
}); | |
table.howHot(); // Hellz yeah! | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment