De quoi devrions-nous parler dans l’article d’aujourd’hui ? Hé hé hé. Nous continuerons l'article précédent pour reconstruire les lacunes et les analyser étape par étape de manière simple et facile à comprendre, afin que chacun puisse avoir un processus d'amélioration étape par étape. Sans plus attendre, entrons dans le vif du sujet. Revoyons d'abord le précédent
fonction ItemSelector(elem,opts){
Ceci.elem = elem ;
This.opts = opte ;
} ;
var ISProto = ItemSelector.prototype ;
ISProto.getElem = fonction(){
Renvoie ce.elem ;
} ;
ISProto.getOpts = fonction(){
Renvoyez this.opts ;
} ;
/* manipulation de données*/
ISProto._setCurrent = fonction (courant){
This.getOpts()["current"] = courant ;
} ;
ISProto.getCurrentValue = fonction (actuel){
Renvoie this.getOpts()["current"] ;
} ;
/* manipulation de données*/
ISProto.init = fonction(){
var ça = ceci ;
This.getOpts()["current"] = null ; // Curseur de données
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() ;
Cela._render(item) ;
}) ;
} ;
ISProto._setItemValue = fonction (valeur){
This.getElem().find(".title div").text(value)
} ;
ISProto._render = fonction (élément) {
var ça = ceci ;
var itemElem = $("
")
.text(item["text"])
.attr("id",item["id"]) ;
Si("0" == élément["désactivé"]){
itemElem.on("clic",function(){
var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(élément) ;
})
.mouseover(function(){
$(this).addClass("item-hover") ;
})
.mouseout(function(){
$(this).removeClass("item-hover") ;
}) ;
>
autre{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
}) ;
>
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
Il n'est pas difficile de voir à partir du code qu'il a été efficacement organisé de manière orientée objet grâce aux caractéristiques grammaticales des "Js", ce qui est bien meilleur que la forme d'organisation procédurale lâche, mais il existe encore de nombreux lieu.
Nous effectuons une reconstruction efficace sur la base des points ci-dessus. Il faut d'abord trier les exigences de ce composant. Les points fonctionnels sont les suivants :
Ce code est très clair et ne nécessite aucune modification, mais vous pouvez étendre la fonction en fonction de la configuration ci-dessus, par exemple en ajoutant l'élément de configuration "mode" pour prendre en charge plusieurs options. Par exemple : "mode de sélection de case à cocher".
L'étape suivante consiste à compléter la logique d'initialisation, comme suit :
var ça = ceci ;
This.getOpts()["current"] = null ; // Curseur de données
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() ;
Cela._render(item) ;
}) ;
} ;
Il y a de nombreux problèmes avec ce code, les responsabilités ne sont pas claires et la logique d'initialisation inclut l'implémentation détaillée des points de fonction.
Continuons à regarder le code de rendu :
ISProto._render = fonction (élément) {
var ça = ceci ;
var itemElem = $("
")
.text(item["text"])
.attr("id",item["id"]) ;
Si("0" == élément["désactivé"]){
itemElem.on("clic",function(){
var onChange = that.getOpts()["change"] ;
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
That._setCurrent(item) ;
onChange && onChange(élément) ;
})
.mouseover(function(){
$(this).addClass("item-hover") ;
})
.mouseout(function(){
$(this).removeClass("item-hover") ;
}) ;
>
autre{
itemElem.css("color","#ccc").on("click",function(){
That.getElem().find(".content .items").hide() ;
That._setItemValue(item["text"]) ;
}) ;
>
itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
Le problème est évident. Si des opérations répétitives sont trouvées, elles doivent être raisonnablement abstraites pour atteindre l'objectif de réutilisation.
L'ensemble du processus d'assemblage comprend l'initialisation, le rendu (liaison d'événements), ainsi que les méthodes d'opération de données associées et les méthodes auxiliaires pour les opérations DOM.
En résumé, après un simple examen, nous devons établir l'objectif opérationnel de la fonction et la répartition des tâches de la ligne de processus principale, et chacun doit en être responsable.
Le but de notre reconstruction est donc très clair, n'est-ce pas ! Cela signifie abstraction des points de fonction et répartition amicale des responsabilités. Alors, comment y parvenir ?
La première étape consiste à établir la méthode de la fonction processus : (interface de la méthode)
ISProto.init = fonction(){
// mets ton code ici !
} ;
ISProto._render = fonction(){
// mets ton code ici !
} ;
La deuxième partie, établissant l'interface de la méthode abstraite :
ISProto._fnItemSelectorDelegateHandler = function(){
// mets ton code ici !
} ;
ISProto._fnTriggerHandler = fonction(){
// mets ton code ici !
} ;
ISProto._addOrRemoveClass = function(){
// mets ton code ici !
} ;
La troisième étape consiste à établir une interface d'exploitation des données :
ISProto._setCurrent = fonction(){
// mets ton code ici !
} ;
ISProto._getCurrent = fonction(){
// mets ton code ici !
} ;
Il y a aussi quelques codes sources complets ci-dessous, voici juste des idées.
(3), code complet pour l'apprentissage, ce code a été testé
fonction ItemSelector(elem,opts){
Ceci.elem = elem ;
This.opts = opte ;
This.current = -1; // Curseur de données
} ;
var ISProto = ItemSelector.prototype ;
/* API getter*/
ISProto.getElem = fonction(){
Renvoie ce.elem ;
} ;
ISProto.getOpts = fonction(){
Renvoyez this.opts ;
} ;
ISProto._getCurrent = fonction(){
Renvoie this.current ;
} ;
/* API getter*/
/* manipulation de données*/
ISProto._setCurrent = fonction (courant){
This.current = courant ;
} ;
ISProto._setItemText = fonction (texte){
This.getElem().find(".title div").text(text) ;
} ;
/* manipulation de données*/
/* mise à jour le 31/01/2015 23:38 */
ISProto._fnTriggerHandler = fonction (index, texte, valeur){
Si(this._isDisabled(value)){
indice = -1 ;
text = this.getOpts()["currentText"] ;
>
This._setItemText(text) ;
This._setCurrent(index) ;
This.getElem().find(".content .items").hide() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
Si(addIs){
elem.addClass(className) ;
>
autre{
elem.removeClass(className) ;
>
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
var ça = ceci ;
This.getElem().on("click","[data-toggle]",function(){
That.getElem().find(".content .items").toggle() ;
}) ;
} ;
ISProto._isDisabled = fonction (valeur){
Retour ("1" == valeur) ? true : false ;
} ;
/* mise à jour le 31/01/2015 23:38 */
ISProto.init = fonction(){
var ça = ceci ;
This._fnItemSelectorDelegateHandler() ;
$.each(this.getOpts()["items"],function(i,item){
Article["index"] = i ;
Cela._render(item) ;
}) ;
This._fnTriggerHandler(this._getCurrent(),this.getOpts()["currentText"],"1") ;
} ;
ISProto._render = fonction (élément) {
var ça = ceci ;
var itemElem = $("
").text(item["text"]).attr("id",item["index"]) ;
var activeClass = ("0" == item["disabled"]) ? "item-hover" : "item-disabled-hover" ;
itemElem.on("clic",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), résumé final
(1) Analyser raisonnablement les exigences fonctionnelles en utilisant la pensée orientée objet.
(2) Organiser notre logique de plug-in sous forme de classes.
(3) Reconstruire en continu l'exemple ci-dessus. Comment effectuer une reconstruction raisonnable ? Ne faites pas de conception excessive et soyez à l’aise avec cela. La méthode recommandée est de combiner la conception procédurale avec la conception orientée objet.
(4), les fonctions associées seront développées dans le prochain article, comme l'attribut "mode", qui prend en charge le mode multi-sélection des cases à cocher lorsqu'il est "1", mais maintenant ce n'est que le mode déroulant par défaut .
Regardez mon article, est-il bien meilleur que le code précédent ? Les amis devraient également réfléchir davantage et faire plus lorsqu'ils réalisent leurs propres projets, et essayer de rendre leur code plus raisonnable.