-
Notifications
You must be signed in to change notification settings - Fork 2
view
A View is stuff you look at, to put it rather technically. Anything that has some underlying
DOM node or tree can be represented as a sudo.View. The sudo.View Object provides a means for
behavior to be encapsulated into an entity that intrinsically has knowlege of its role, defined by you.
In the master branch, jQuery is assumed to be present and is used for DOM manipulation by View classes.
NOTE: we have intentionally resisted the urge to abstract jQuery-related DOM manipulation into the sudo.View, keeping overlapping functionality at zero. This will keep the core library small and on-point
###Constructing a View
Two optional arguments can be passed to a sudo.View:
var foo = new sudo.View('#bar', {baz: 'qux'});
####el
The first argument becomes the DOM element residing at view.$el. If it is omitted, a DOM element is created outside of the DOM (a fragment), by default a 'div' (configurable via tagName in the second argument). This first argument, when included, should be a legal jQuery selector. This selector is passed through jQuery's $ function and the returned value is set at view.$el.
There is more to this first argument, see the "setEl" section below.
####data
The second argument can be:
- An object literal that will become the initial state of this view's model.
- A reference to an already instantiated Model Class.
- Nothing. No model for this View
###Subclassing View
Most of your projects view classes will be created this way, as a subclass of sudo.View with some custom functionality:
var Foo = function(el, data) {
// do stuff before calling 'super' constructor
this.construct(el, data);
// do stuff after calling 'super' constructor
};
Foo.prototype = $.extend(Object.create(sudo.View.prototype), {
bar: function bar() {
// do some bar-ing
},
baz: function baz(qux) {
// do some baz-ing with qux
}
});
###setEl([el])
This method is called directly from the constructor with the first argument passed (if present), but can be called manually at any time to replace this object's $el if you need to. The "el" argument can be:
- Any legal jQuery selector
- A "raw" DOM Element
- An already "jquerified" DOM Element
- Nothing
In the "nothing" case (the "el" argument is falsy), an $el will be constructed and set at the same (this.$el) location as if you had passed one. In this case the View will inspect its model for
a few pieces of information:
-
tagName. Will default to 'div' if not found. Any legal DOM tagName can be used.
-
attributes. If found will be set on the newly created Element. Any legal attribute for a DOM Element may be used.
var foo = new sudo.View(null, { tagName: 'aside', attributes: { id: 'bar', 'class': 'baz', 'data-qux': 'vot' } });
// foo.$el => [
]
NOTE: the Element has been passed through jQuery at this point. The "raw" DOM is always available at this.$el[0]
###$(selector)
Every view's $el is already 'jQuerified' and can be treated as such:
this.$el.on('click', '.btn', this.handleClick.bind(this));
If you want to find a specific element in this.$el you can use the View Class $ convenience method which scopes all DOM queries to this Class' $el:
this.$('.foo').hide();
The nice thing about the above statement is that any elements with a class of 'foo' outside of the current
view's $el would not be found. $ is synonymous with this.$el.find.
###Premier
Similar to the Cocoa idea of a 'first responder' is the sudo.premier. A view declaring itself to be the premier is guaranteed to be the only premier at that given time. The two methods exposed by a view for premiership are:
####becomePremier
- tell an existing premier, if it exists, to resign
- set
this.isPremierto true - set sudo.premier to
this
What happens then? That is up to the developer. You should override this method in your subclass to do your premier-stuff, just remember to call the 'super' method:
becomePremier: function() {
this.$el.addClass('look-at-me');
return this.base('becomePremier');
}
####resignPremier([cb])
- set
this.isPremierto false - If the sudo.Premier is this View, set sudo.premier to null.
Notice the optional 'cb' argument. It is a function that, if present, will be called after the above 2 steps. This is done internally as becomePremier actually calls resignPremier passing it a function to call when doing so. Why? This allows developers to know that any given View Object may set itself to premier status if asked, but will not do so until any pre-existing premier has actually resigned.
What happens after resignation? Again, that is up to the developer. Override this method to actually perform your resignation specific behavior. Also remember to set the correct signature for this method when overriding it as becomePremier will call it with a 'cb' argument.
resignPremier: function(cb) {
this.$el.removeClass('look-at-me');
return this.base('resignPremier', cb);
}
###init
Optional method that if present, will be called from the constructor of your View subclass. This method is useful for Coffeescript implementations (and perhaps other pre-processors) as they do not need to write their own constructors. However, feel free to write an 'init' method if you choose and it will be called. The call comes during this.construct(el, data).
var Foo = function(el, data) {
this.construct(el, data); // init called from the super if found
};
Foo.prototype = $.extend(Object.create(sudo.View.prototype), {
bar: function bar() {
// do some bar-ing
},
baz: function baz(qux) {
// do some baz-ing with qux
},
init: function init() {
// do some initializing...
}
});