update example

This commit is contained in:
rolux 2012-05-29 12:22:06 +02:00
parent 7dd9169b3f
commit 2223064d35

View file

@ -1,3 +1,16 @@
/*
The following examples explain the common design pattern for Ox.js UI widgets:
an inheritance model that is neither classical nor prototypal, but "parasitical"
(a term coined by <a
href="http://www.crockford.com/javascript/inheritance.html">Douglas
Crockford</a>). In a nutshell, "instances" are created by augmenting other
instances, but in addition to private members (`var foo`) and public members
(`that.bar`), they can have shared private members (`self.baz`). `self` cannot
be accessed from outside, but since `self` itself is an argument of the
"constructor", an instance can inherit its parent's `self` by passing its own
`self`.
*/
'use strict';
/*
@ -14,31 +27,31 @@ Ox.load('UI', function() {
First, lets build the most basic Box widget. A widget is a "constructor"
function that takes two (optional) arguments, `options` and `self`, and
returns a widget object. It's not a constructor in JavaScript terms though:
It doesn't have to be called with `new`, and doesn't return an instance of
It doesn't have to be called with `new`, and doesn't return an `instanceof`
anything. It just enhances another widget object and returns it.
*/
Ox.My.Box = function(options, self) {
/*
This is how every widget "constructor" begins. `self` is the widget's
shared private object. It is private since it can only be accessed
inside the widget, but shared because it can be passed to a widget upon
its creation.
shared private object.
*/
self = self || {};
/*
`that` is the widget itself, its public object, or, in JavaScript terms,
its `this`. Every widget "inherits" from another widget, by simple
its `this`. Every widget "inherits" from another widget by simple
assignment. All public properties of the "super" widget, i.e. all
properties of its `that`, will be present on our own `that`. In this
case, we use Ox.Element, the "root" widget at the end of the inheritance
chain, and pass an empty options object. But we always pass our own
`self`, which means that any property that Ox.Element (or any other
widget in the inheritance chain) adds to self will be present on our own
`self`. Then we call the public `defaults` and `options` methods.
`defaults` assigns the defaults object to `self.defaults` and copies it
to `self.options`, then `options` extends `self.options` with the
options object.
widget in the inheritance chain) adds to `self` will be present on our
own `self`. Then we call the public `defaults`, `options` and `update`
methods of Ox.Element. `defaults` assigns the defaults object to
`self.defaults` and copies it to `self.options`, `options` extends
`self.options` with the options object, and `update` adds one or more
callbacks that are invoked whenever, by way of calling the `options`
method, a property of `self.options` is modified or added.
*/
var that = Ox.Element({}, self)
.defaults({
@ -52,24 +65,13 @@ Ox.load('UI', function() {
});
/*
Ox.Element, and every widget that inherits from it, has a private
`self.setOption` method that is invoked whenever, by way of calling the
public `that.options` method, a property of `self.options` is modified
or added. If we don't want to react to such changes, we can leave
`self.setOption` untouched. In this case though, we want to update color
and size, so we just overwrite `self.setOption`.
*/
/*
The following part of the "constructor" function can be thought of as
the "initializer", and contains everything needed to set up the
"instance". In this case, we just define a minimum and maximum size and
then set the widget's color and size. We could have used `var minSize`
and `var maxSize` here, but by using `self` for private variables that
we want to be accessible across all the widget's methods, we can be sure
that inside such methods, any local `var` is actually local to the
method. We could have set color and size directly, too, but as we also
need to set them in `self.setOption`, we create methods for both cases.
The second part of the "constructor" function can be thought of as the
"initializer", and contains everything needed to set up the "instance".
In this case, we just define a minimum and maximum size and then set the
widget's color and size. We could have used `var minSize` and `var
maxSize` here, but by using `self` for private variables that we want to
be accessible across all the widget's methods, we can be sure that
inside such methods, any local `var` is actually local to the method.
*/
self.minSize = 128;
self.maxSize = 384;
@ -78,13 +80,13 @@ Ox.load('UI', function() {
setSize();
/*
Now we declare the widget's private methods. These are simple function
Third, we declare the widget's private methods. These are just function
declarations, hoisted to the top of the "constructor".
*/
function setColor() {
/*
To interact with the DOM, Ox.Element (and any widget derived from
it) wraps jQuery. If you type `Ox.Element()` in the console, you
it) wraps jQuery. If you type Ox.Element() in the console, you
will get something like `[<div class="OxElement"></div>]`, and the
widget's prototype has all the methods of a `$('<div>')`, with
proper chaining. If you have `var $d = $('<div>'), $e =
@ -98,8 +100,8 @@ Ox.load('UI', function() {
function setSize() {
/*
Before setting the size, we make sure the value is between minSize
and maxSize.
Before setting the size, we make sure the value is between `minSize`
and `maxSize`.
*/
self.options.size = Ox.limit(
self.options.size, self.minSize, self.maxSize
@ -127,7 +129,7 @@ Ox.load('UI', function() {
};
/*
At the very end of the "constructor", we always return `that`. And
And finally, at the very end of the "constructor", we return `that`. And
that's it.
*/
return that;
@ -135,7 +137,12 @@ Ox.load('UI', function() {
};
/*
`Ox.My.Box({size: 256}).appendTo(Ox.$body).showOptions()`
<pre>
Ox.My.Box({color: [255, 0, 0]})
.appendTo(Ox.$body)
.options({size: 256})
.showOptions();
</pre>
*/
Ox.My.RoundedBox = function(options, self) {