Despite having event delegation, and a Class architecture, sometimes it's necessary to create widget like features with JavaScriptMVC. These are little bits of UI functionality that you want to be able to create many of, but each will have its own state.
Fortunately, JavaScriptMVC has you covered with Controller.Stateful.
This demo shows you how to create stateful base UI functionality that can be reused via inheritance in other Controllers.
Specifically, this demo shows two classes that inherit from MVCUI.FixedBoxController making their instances able to maintain a fixed position. But, each controller (RedsController and BluesController) has its own functionality.
Click a RedsController instance to make it count. Mouseover a BluesController instance to make it count. Try it now!
Notice how each red and blue instance has its own state. Lets look at the code for each of these controllers:
RedsController = MVCUI.FixedBoxController.extend(reds',{
click: function(params){
this.count = this.count != null ? this.count + 1 : 0
this.element.innerHTML = this.count;
}
});
BluesController = MVCUI.FixedBoxController.extend('blues',{
mousemove: function(params){
this.count = this.count != null ? this.count + 1 : 0
this.element.innerHTML = this.count;
}
})
Notice that each controller inherits from MVCUI.FixedBoxController but defines its own functionality for counting. Even more interesting is that it expects this.count to exist for the individual instance between calls to click or mouseover. Lets see how we created these instances:
blue_bottom_right = new BluesController({bottom: 20, right: 20});
blue_top_right = new BluesController({top: 20, right: 20});
red_top_left = new RedsController({top: 20, left: 20});
red_bottom_left = new RedsController({bottom: 20, left: 20});
Now lets see how FixedBoxController lets us position our instances.
FixedBoxController does primarly 3 things:
MVCUI.FixedBoxController = MVC.Controller.Stateful.extend({
init: function(options){
// 1: create instance element
},
scroll: function(event){
// 2. on window scroll, if IE, position element correctly
},
resize : function(event){
// 3. on window resize, if IE, position element correctly
}
})
#2 and #3 are pretty understandable - listen for when you need to reposition your element, then put it in the right place.
#1 is where the magic of Controller.Stateful needs to be setup. As all Controller.Stateful instances must have an element, most of the init code deals with creating, styling and setting the instance's element. Lets go through it line by line:
init : function( options){
//saves the options to the instance
this.options = options;
//Create a div to hold the box and style it
this.element = document.createElement('div');
this.element.className = this.Class.singularName;
this.set_style();
document.body.appendChild(this.element);
//Start listening for events inside the box
this._super(this.element);
//Draw content in element (must happen after super)
this.render({to: this.element});
}
So what does:
blue_bottom_right = new BluesController({bottom: 20, right: 20});
Actually do?
Well ... what does:
clicking a red element
Actually do?