PlastronJS
PlastronJS
MVC for Closure Library
- Define schemas on models
- Controls built on goog.ui.Component
- Control level event system
- Convenient model bindings
- Mediator
- Store
- also router and syncs
Schema for models
WeatherDemo.model.City.Schema = {
'celcius': {
get: function(temp) {
return 5 / 9 * (temp - 32);
},
/** @this {mvc.Model} */
set: function(num, opt_silent) {
this.set('temp', num * 9 / 5 + 32, opt_silent);
},
require: ['temp']
}
};
or convenience functions
this.alias('farenheit', 'temp');
Mediator
- app wide messaging
- namespace messages
- can register objects to broadcast, then will decorate with broadcast method
- can initialize and dispose based on available message
- message matching with customizable wildcards
WeatherDemo.Mediator.register(this, 'chooseCity');
// then
this.broadcast('chooseCity', this.getModel().get('id'));
WeatherDemo.Mediator.on('chooseCity', function(id) {...});
Store
- single store for retrieval of models
- can create models given a type
- will retrieve models given an id (and update new models id when given)
WeatherDemo.Store = new mvc.Store(WeatherDemo.model.City);
WeatherDemo.Store.get(city['id']);
Let's talk about components
- mvc.Layout built on goog.ui.Component
- Component level events
- Handy selectors
- More to come
- mvc.Control built on mvc.Layout
- bindings to a model
- can handle models and collections
2 types of component
// render to create a component DOM structure
myComponent.render(el);
// this will fire:
myComponent.createDom(); // create the DOM structure, and set this.element_;
// decorate to use existing DOM structure
myComponent.decorate(el);
// this will fire:
myComponent.canDecorate(el);// return if DOM structure is eligible
myComponent.decorateInternal(el); // any transforms on the DOOM needed
Then enterDocument() will fire.
Component Lifecycle
Control events
- All control events use event delegation (to root element)
- Handlers are fired based on priority first (then order)
- returns an object that can .fire() the handler and .off()
this.on(eventType, fn, opt_selector, opt_handler, opt_priority).fire();
Convenient model bindings
model bindings
this.autobind('.city', 'City: {$city}');
this.autobind('.temp', '{$farenheit} °F');
this.bind('temp', function(temp) {
$(this.getElement()).css('left', temp * 10 - 300);
}).fire();
autobind does it all!
this.autobind('', {
reqs: ['celcius'],
reqClass: ['hot', 'mild'],
chooseClass: function(celcius) {
if (celcius > 30)
return 'hot';
if (celcius < 20)
return 'mild';
}
});
even two way binding
this.autobind('.city', '{$city}');
this.autobind('.temp', '{$temp}');
this.autobind('.celcius', '{$celcius}');
// used to blur on enter so autobind will apply
this.on(goog.events.EventType.KEYUP, function(e) {
if (e.keyCode === goog.events.KeyCodes.ENTER) {
e.target.blur();
}
}, 'input');
autolist
this.autolist(WeatherDemo.control.Simple, content);
or override placement:
WeatherDemo.control.List.prototype.placeChild_ = function(
contentEl, child, index) {
$(child.getElement()).css({
'top': index * 45
});
};