Make a component for Vizabi
Base class for components. It extends Vizabi.Events
. You may think of Vizabi.Component
similar to a Controller-View. Components can be rendered to a DOM element and have support for templating and model binding.
The following example shows a very simple component implementation:
// create a new component fo year display
var YearDisplay = Vizabi.Component.extend({
init: function(config, parent) {
this.name = "year-display";
this.template = '<h2><%= time %></h2>';
this.template_data = { time: "2012" };
this._super(config, parent);
}
});
var component = new YearDisplay({
placeholder: document.getElementById("placeholder")
});
component.render();
/*
* at this point, #placeholder should contain the following html:
* <h2>2012</h2>
*/
Components may also be registered if reusable. Example:
Vizabi.Component.extend("year-display", {
/* methods */
});
Vizabi comes with many built-in reusable components. You can find them under src/components
. All of them extend Vizabi.Component
.
Sub-components
Components may also instantiate subcomponents. Assuming year-display
from the previous example is registered, we can create a new component that uses it.
var CustomComponent = Vizabi.Component.extend({
init: function(config, parent) {
this.name = "my_component";
this.template = '<div><div class="display"></div></div>';
// "year-display" component will be rendered in the .display div
this.components = [{
component: "year-display",
placeholder: ".display"
}];
this._super(config, parent);
}
});
var component = new CustomComponent({
placeholder: document.getElementById("placeholder")
});
component.render();
/*
* at this point, #placeholder should contain the following html:
* <div><div class="display"><h2>2012</h2></div></div>
*/
Model binding
The following code is an example of model binding at a component level:
// create a new model
var TimeModel = Vizabi.Model.extend("mytime", {
init: function(values, parent, bind) {
this._type = "time";
// default values for time model
values = Vizabi.utils.extend({
value: 1800,
start: 1800,
end: 2015
}, values);
this._super(values, parent, bind);
}
});
var YearDisplay = Vizabi.Component.extend({
init: function(config, parent) {
this.name = "year-display";
this.template = '<h2><%= time %></h2>';
this.model = new TimeModel();
this.template_data = {
time: this.model.value // value from model
};
this._super(config, parent);
var _this = this;
this.model.on({
"change": function() {
_this.update();
}
});
},
update: function() {
this.element.innerHTML = this.model.value;
}
});
var component = new YearDisplay({
placeholder: document.getElementById("placeholder")
});
component.render();
/*
* at this point, #placeholder should contain the following html:
* <h2>1800</h2>
*/
component.model.value = 2012;
/*
* at this point, #placeholder should contain the following html:
* <h2>2012</h2>
*/
Useful methods
Every Vizabi.Component
has three special methods:
- resize(): called when the container detects a resize event
- readyOnce(): called only once when both compoment’s DOM and model are ready
- ready(): called when DOM and model are ready (multiple times)
Since we know that the DOM is ready in these methods, we can use this.element
to access the root node of the component’s template and this.placeholder
to access the placeholder node. Example:
var myComponent = Vizabi.Component.extend({
init: function(config, parent) {
// ...
},
readyOnce: function(evt) {
this.element.innerHTML = "Hello World";
},
ready: function(evt) {
this.element.innerHTML = "I'm ready!";
},
resize: function(evt) {
this.element.innerHTML = "I'm resizing!";
}
});
And since we know that the model is ready in readyOnce
and ready
, we can use this.model
to access its properties and data:
var myComponent = Vizabi.Component.extend({
init: function(config, parent) {
// ...
},
ready: function(evt) {
console.log(this.model);
}
});
Checkout how Vizabi’s timeslider component uses such methods here.
Note that listening to the model’s ready
event is different than using the component’s ready()
method, because in the later, we ensure that the DOM is also ready, not only the model