What should we talk about in today’s article? Hey hey hey. We will continue the previous article to reconstruct the deficiencies and analyze them step by step in a simple and easy-to-understand way, so that everyone can have a step-by-step improvement process. Without further ado, let’s get to the point. Let us first review the previous
function ItemSelector(elem,opts){
This.elem = elem ;
This.opts = opts ;
} ;
var ISProto = ItemSelector.prototype ;
ISProto.getElem = function(){
Return this.elem ;
} ;
ISProto.getOpts = function(){
Return this.opts ;
} ;
/* data manip*/
ISProto._setCurrent = function(current){
This.getOpts()["current"] = current ;
} ;
ISProto.getCurrentValue = function(current){
Return this.getOpts()["current"] ;
} ;
/* data manip*/
ISProto.init = function(){
var that = this ;
This.getOpts()["current"] = null ; // Data cursor
This._setItemValue(this.getOpts()["currentText"]) ;
var itemsElem = that.getElem().find(".content .items") ;
This.getElem().find(".title div").on("click",function(){
itemsElem.toggle() ;
}) ;
This.getElem().find(".title span").on("click",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
Item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;
ISProto._setItemValue = function(value){
This.getElem().find(".title div").text(value)
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(item["text"])
.attr("id",item["id"]) ;
If("0" == item["disabled"]){
itemElem.on("click",function(){
var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(item) ;
})
.mouseover(function(){
$(this).addClass("item-hover") ;
})
.mouseout(function(){
$(this).removeClass("item-hover") ;
}) ;
}
else{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
}) ;
}
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
It is not difficult to see from the code that it has been effectively organized in an object-oriented manner through the grammatical features of "Js", which is much better than the loose procedural form of organization, but there are still many shortcomings. place.
We carry out effective reconstruction based on the above points. We must first sort out the requirements of this component. The functional points are as follows:
This code is very clear and does not require any modification, but you can extend the function based on the above configuration, such as adding the configuration item "mode" to support multiple options. For example: "checkbox selection mode".
var that = this ;
This.getOpts()["current"] = null ; // Data cursor
This._setItemValue(this.getOpts()["currentText"]) ;
var itemsElem = that.getElem().find(".content .items") ;
This.getElem().find(".title div").on("click",function(){
itemsElem.toggle() ;
}) ;
This.getElem().find(".title span").on("click",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
Item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;
There are many problems with this code, the responsibilities are unclear, and the initialization logic includes the detailed implementation of function points.
Let’s continue looking at the rendering code:
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(item["text"])
.attr("id",item["id"]) ;
If("0" == item["disabled"]){
itemElem.on("click",function(){
var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(item) ;
})
.mouseover(function(){
$(this).addClass("item-hover") ;
})
.mouseout(function(){
$(this).removeClass("item-hover") ;
}) ;
}
else{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
}) ;
}
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
The problem is obvious. If repetitive operations are found, they should be reasonably abstracted to achieve the purpose of reuse.
The entire assembly process includes initialization, rendering (event binding), as well as related data operation methods and auxiliary methods for DOM operations.
In summary, after a simple combing, we should establish the operational purpose of the function and the task allocation of the main process line, and everyone should be responsible for it.
So the purpose of our reconstruction is very clear, right! It means abstraction of function points and friendly division of responsibilities. So how do we achieve that?
The first step is to establish the process function method: (method interface)
ISProto.init = function(){
// put you code here !
} ;
ISProto._render = function(){
// put you code here !
} ;
The second part, establishing the abstract method interface:
ISProto._fnItemSelectorDelegateHandler = function(){
// put you code here !
} ;
ISProto._fnTriggerHandler = function(){
// put you code here !
} ;
ISProto._addOrRemoveClass = function(){
// put you code here !
} ;
The third step is to establish a data operation interface:
ISProto._setCurrent = function(){
// put you code here !
} ;
ISProto._getCurrent = function(){
// put you code here !
} ;
There are also some complete source codes below, here are just ideas.
(3), complete code for learning, this code has been tested
function ItemSelector(elem,opts){
This.elem = elem ;
This.opts = opts ;
This.current = -1; // Data cursor
} ;
var ISProto = ItemSelector.prototype ;
/* getter api*/
ISProto.getElem = function(){
Return this.elem ;
} ;
ISProto.getOpts = function(){
Return this.opts ;
} ;
ISProto._getCurrent = function(){
Return this.current ;
} ;
/* getter api*/
/* data manip*/
ISProto._setCurrent = function(current){
This.current = current ;
} ;
ISProto._setItemText = function(text){
This.getElem().find(".title div").text(text) ;
} ;
/* data manip*/
/* update on 2015 1/31 23:38 */
ISProto._fnTriggerHandler = function(index,text,value){
If(this._isDisabled(value)){
index = -1 ;
text = this.getOpts()["currentText"] ;
}
This._setItemText(text) ;
This._setCurrent(index) ;
This.getElem().find(".content .items").hide() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
If(addIs){
elem.addClass(className) ;
}
else{
elem.removeClass(className) ;
}
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
var that = this ;
This.getElem().on("click","[data-toggle]",function(){
That.getElem().find(".content .items").toggle() ;
}) ;
} ;
ISProto._isDisabled = function(value){
Return ("1" == value) ? true : false ;
} ;
/* update on 2015 1/31 23:38 */
ISProto.init = function(){
var that = this ;
This._fnItemSelectorDelegateHandler() ;
$.each(this.getOpts()["items"],function(i,item){
Item["index"] = i ;
That._render(item) ;
}) ;
This._fnTriggerHandler(this._getCurrent(),this.getOpts()["currentText"],"1") ;
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
").text(item["text"]).attr("id",item["index"]) ;
var activeClass = ("0" == item["disabled"]) ? "item-hover" : "item-disabled-hover" ;
itemElem.on("click",function(){
That._fnTriggerHandler(item["index"],item["text"],item["disabled"]) ;
})
.mouseover(function(){
That._addOrRemoveClass($(this),activeClass,true) ;
})
.mouseout(function(){
That._addOrRemoveClass($(this),activeClass,false) ;
}) ;
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
(4), final summary
(1) Reasonably analyze functional requirements using object-oriented thinking.
(2) Organize our plug-in logic in the form of classes.
(3) Continuously reconstruct the above example. How to perform reasonable reconstruction? Don’t over-design and be comfortable with it. The recommended way is to combine procedural design with object-oriented design.
(4), related functions will be expanded in the next article, such as the "mode" attribute, which supports checkbox multi-selection mode when it is "1", but now it is only the default drop-down mode.
Look at my article, is it much better than the previous code? Friends should also think more and do more when doing their own projects, and try to make their code more reasonable.