This is a really helpful feature of MooTools that a few people know and use. Basically, there is a pair of 2 Function prototypes called ‘overloadGetter‘ and ‘overloadSetter‘. They are very simple in what they can provide. Say, you have a function that is a private property setter in a Class that takes 2 arguments: key & value. After a while, you may get bored having to call it all the time for every property you wish to add or having to write object loops for longer updates.
By defining using the Function decorator overloadSetter, you can – without any code adjustment – make your single key/value pair setter take an object and automatically iterate through the properties for you.
Similarly, by using the decorator overloadGetter, you can pass on multiple properties to retrieve that you are interested in – and it will return a single object with all your properties of interest as key.
Pretty cool?
Here’s a real world example. Let’s say, you are making a MVC Model Class that you’d like to use to deal with data objects and dispatch events.
(function() { // private real setter functions, not on prototype, see note on .set var _set = function(key, value) { // needs to be bound the the instance. if (!key || typeof value === undefined) return this; // no change? return. better rely on _.js _.eq but this is crude and works for primitives. if (this._attributes[key] && this._attributes[key] === value) return this; if (value === null) { this._attributes.delete(key); // delete = null. } else { this._attributes[key] = value; } // fire an event. return this.fireEvent("change:" + key, value); }.overloadSetter(); this.Model = new Class({ _attributes: {}, // initial private object, Implements: [Options, Events], initialize: function(data, options) { data && typeOf(data) === 'object' && this.set(data); this.setOptions(options); }, set: function() { // call the real getter. we proxy this because we want // a single event after all properties are updated _set.apply(this, arguments); this.fireEvent("change"); }, get: function(key) { // and the overload getter return (key && typeof this._attributes[key] !== undefined) ? this._attributes[key] : null; }.overloadGetter() }); })(); // now make an abstraction of your Model class for users var User = new Class({ Extends: Model, _attributes: { name: "Please enter your name", email: "Enter your email address" } }); // initialise your User Model with default data and set some property change events var user = new User(null, { "onChange:email": function(value) { // can dispatch to controller/view the change console.log("new email now is", value); }, "onChange:name": function(value) { console.log("new name now is", value); }, onChange: function() { console.log("data has changed!"); } }); // let's test this. initial set via single value set: user.set("email", "dimitar@securemail.com"); // now let's try multiple properties at the same time: user.set({ "email": "dimitar@securemail.com", "name": "coda" }); // get the name console.log(user.get("name")); // coda; // get multiple properties in a single object console.log(user.get(["name","email"])); // Object { name="coda", email="dimitar@securemail.com"}
View and play with this on http://jsfiddle.net/dimitar/39x7T/
That’s about it. Please note that this Class was only created for the purposes of a demo and is not meant to be used in a real MVC pattern – look at Composer.js (for MooTools), Backbone.js or Ember.js – formerly Sprout Core – if you are interested in doing serious event-based application development.
GitHub flavoured markdown enabled.