ui.js | |
---|---|
/*global Ply, jQuery */
/*jshint eqeqeq: true, curly: true, white: true */ | |
The UI module provides most of the user-facing functionality for Ply. | |
Utility methods | |
Polyfills | |
Create a polyfill for | |
Source code from: Mozilla Developer Network. | if (!Object.create) {
Object.create = function (o) {
if (arguments.length > 1) {
throw new Error('Object.create implementation only accepts first parameter.');
}
function F() {}
F.prototype = o;
return new F();
};
}
Ply.ui = (function ($) { |
Private Functions/Variables | |
Instantiate ViewThis is a private function which is called when a view is started.
The function expects several arguments — the name of the view,
the jQuery object tied to the view, the options and data objects,
and a delegate. The last three may be undefined, but | function instantiateView(name, view, options, data, delegate) { |
Alias | var self = this; |
NameAssign the view's name to its | this.name = name; |
ViewAssign the view to its | this.view = view; |
DelegateAssign the delegate to its | this.delegate = delegate; |
OptionsMerge | this.options = $.extend({}, Ply.config.ui.defaults, this.options, options); |
DataMerge the | this.data = $.extend({}, this.data, data); |
ObjectsIf | if (this.__objects) { |
Create an empty objects hash to store the objects. | this.objects = {}; |
Create a function for binding objects. A function is created so
the view or clients can call | this.__bindObjects = function () { |
Iterate over the own properties of | for (var id in self.__objects) {
if (self.__objects.hasOwnProperty(id)) { |
Attach the result of calling | |
We intentionally use | self.objects[id] = self.view.find(self.__objects[id]);
}
}
}; |
Invoke | this.__bindObjects();
} |
PartialsIf | if (this.__partials) { |
Create empty hash to store partials. | this.partials = {}; |
Declare function for binding partials. Function is created for same purposes
as | this.__bindPartials = function () { |
Iterate over the own properties of | for (var id in self.__partials) {
if (self.__partials.hasOwnProperty(id) &&
self.objects[id] &&
self.objects[id].length) { |
Assign to the respective property of | self.partials[id] = Ply.ui.register(self.__partials[id], {
view: self.objects[id],
delegate: self
});
}
}
}; |
Invoke | this.__bindPartials();
} |
NotificationsIf | if (this.__notifications) { |
Iterate over the own properties of | for (var note in this.__notifications) {
if (this.__notifications.hasOwnProperty(note)) { |
Listen to the respective notification using the handler string to reference the given method of the view. | Ply.core.listen(note, this[this.__notifications[note]], this);
}
}
} |
InitIf an | if (this.__init && typeof this.__init === 'function') {
this.__init();
} |
Return the view. | return this;
} |
Public Methods & Properties | |
Return the public methods and properties to be accessible on | return { |
fnThe | fn: {}, |
DefineThis is the most common method used on | define: function (name, prototype) { |
Alias | var self = this, |
BaseCreate a | base = Ply.config.ui.base || {}; |
ReadIf no read method has been defined, create one using the | if (!Ply.read[name]) {
Ply.read.add(name, prototype.__url || Ply.config.read.urlGenerator(name));
} |
Start-up methodReturn the result of | this.fn[name] = function (view, options, data, delegate) { |
The receiving object is a new object with the | return instantiateView.call(Object.create(self.fn[name].impl),
name, view, options, data, delegate);
}; |
ImplementationSave the implementation as a property of the startup function.
The implementation is an object with the base object as its prototype.
We first create an empty object with the base as its prototype, and then
perform a deep copy of the | this.fn[name].impl = $.extend(Object.create(base), prototype); |
Alias | this.fn[name].impl.read = Ply.read[name];
}, |
RegisterPublic method for starting up views; accepts a view name, along with
some options. The | register: function (name, options) { |
Alias | var config = Ply.config.ui; |
Default empty object if options is not defined, or is not an object. | options = options && typeof options === 'object' ? options : {}; |
Register callbackAn optional callback is available for client use
by overriding | if (config.onRegister && typeof config.onRegister === 'function') { |
| if (config.onRegister(name, options) === false) {
return;
}
} |
Autogenerating ViewsIf no view or selector is provided, generate a selector based on the configured implementation. Note that this is the preferred method to register objects. The philosophy of Ply encourages users to rely on well-defined conventions for tying together DOM elements and their respective behaviors. | if (!options.view) {
options.view = config.selectorGenerator(name);
Ply.core.log('No view name supplied, implying: ' + options.view);
} |
ResultWe return the result of | return this.start(name, options);
}, |
StartThe start method is primarily to be used internally, but is left available to clients to call directly. It is simply a wrapper around starting the view. | start: function (name, o) { |
Log to the console the view's name. | Ply.core.log('trying start: ' + name, 'info'); |
Wrap the initialiazation in a try/catch block, and log any errors
through | try {
return this.fn[name]($(o.view), o.options, o.data, o.delegate);
}
catch (ex) {
Ply.core.log(name + ' failed to start.');
Ply.core.error(ex, 1); |
If debug mode is enabled, allow the error to bubble. | if (Ply.core.debugOn) {
throw ex;
}
}
}
}; |
Alias | })(jQuery); |
↪ Config | |