今日の記事では何を話しましょうか?おいおいおい。前回の記事に引き続き、誰もが段階的に改善プロセスを行えるように、欠陥を再構成し、シンプルでわかりやすい方法で段階的に分析していきます。早速、本題に入りましょう。まずは前回の
functionItemSelector(elem,opts){
This.elem = elem ;
This.opts = オプト ;
} ;
var ISProto = ItemSelector.prototype ;
ISProto.getElem = function(){
this.elem を返します ;
} ;
ISProto.getOpts = function(){
this.opts を返します ;
} ;
/* データ操作*/
ISProto._setCurrent = function(current){
This.getOpts()["current"] = 現在 ;
} ;
ISProto.getCurrentValue = function(current){
this.getOpts()["current"] を返します ;
} ;
/* データ操作*/
ISProto.init = function(){
var that = this ;
This.getOpts()["current"] = null // データ カーソル
;
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(".タイトルスパン").on("クリック",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;
ISProto._setItemValue = 関数(値){
This.getElem().find(".title div").text(value)
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(アイテム["テキスト"])
.attr("id",item["id"]) ;
If("0" == item["無効"]){
itemElem.on("クリック",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")) ;
} ;
コードから、「Js」の文法的特徴を通じてオブジェクト指向の方法で効果的に編成されていることがわかります。これは、緩やかな手続き型の編成よりもはるかに優れていますが、まだ多くの点があります。欠点。
このコードは非常に明確であり、変更は必要ありませんが、複数のオプションをサポートするために構成項目「mode」を追加するなど、上記の構成に基づいて機能を拡張できます。例:「チェックボックス選択モード」。
var that = this ;
This.getOpts()["current"] = null // データ カーソル
;
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(".タイトルスパン").on("クリック",function(){
itemsElem.toggle() ;
}) ;
$.each(this.getOpts()["items"],function(i,item){
item["id"] = (new Date().getTime()).toString() ;
That._render(item) ;
}) ;
} ;
このコードには多くの問題があり、責任が不明瞭で、初期化ロジックにはファンクション ポイントの詳細な実装が含まれています。
レンダリング コードを続けて見てみましょう:
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
.text(アイテム["テキスト"])
.attr("id",item["id"]) ;
If("0" == item["無効"]){
itemElem.on("クリック",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")) ;
} ;
問題は明らかです。反復的な操作が見つかった場合は、再利用の目的を達成するために合理的に抽象化する必要があります。
アセンブリ プロセス全体には、初期化、レンダリング (イベント バインディング) に加え、関連するデータ操作メソッドと DOM 操作の補助メソッドが含まれます。
要約すると、簡単に検討した後、機能の運用目的とメインプロセスラインのタスク割り当てを確立し、全員がそれに責任を負う必要があります。
私たちの再建の目的は非常に明確ですよね!それは機能点の抽象化と責任の友好的な分割を意味します。では、それをどのように達成するのでしょうか?
最初のステップは、プロセス関数メソッドを確立することです: (メソッド インターフェイス)
ISProto.init = function(){
// ここにコードを入力します !
} ;
ISProto._render = function(){
// ここにコードを入力します !
} ;
2 番目の部分、抽象メソッド インターフェイスの確立:
ISProto._fnItemSelectorDelegateHandler = function(){
// ここにコードを入力します !
} ;
ISProto._fnTriggerHandler = function(){
// ここにコードを入力します !
} ;
ISProto._addOrRemoveClass = function(){
// ここにコードを入力します !
} ;
3 番目のステップは、データ操作インターフェイスを確立することです:
ISProto._setCurrent = function(){
// ここにコードを入力します !
} ;
ISProto._getCurrent = function(){
// ここにコードを入力します !
} ;
以下に完全なソース コードもいくつかありますが、ここでは単なるアイデアを示します。
(3)、学習用の完全なコード。このコードはテスト済みです
functionItemSelector(elem,opts){
This.elem = elem ;
This.opts = オプト ;
This.current = -1; // データカーソル
} ;
var ISProto = ItemSelector.prototype ;
/* ゲッター API*/
ISProto.getElem = function(){
this.elem を返します ;
} ;
ISProto.getOpts = function(){
this.opts を返します ;
} ;
ISProto._getCurrent = function(){
this.current を返します ;
} ;
/* ゲッター API*/
/* データ操作*/
ISProto._setCurrent = function(current){
This.current = 現在 ;
} ;
ISProto._setItemText = function(text){
This.getElem().find(".title div").text(text) ;
} ;
/* データ操作*/
/* 2015 1/31 23:38 更新 */
ISProto._fnTriggerHandler = function(index,text,value){
If(this._isDisabled(value)){
インデックス = -1 ;
text = this.getOpts()["currentText"] ;
}
This._setItemText(テキスト) ;
This._setCurrent(index) ;
This.getElem().find(".content .items").hide() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
If(addIs){
elem.addClass(クラス名) ;
}
それ以外{
elem.removeClass(className) ;
}
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
var that = this ;
This.getElem().on("クリック","[データトグル]",function(){
That.getElem().find(".content .items").toggle() ;
}) ;
} ;
ISProto._isDisabled = 関数(値){
戻り値 ("1" == 値) true : false ;
} ;
/* 2015 1/31 23:38 更新 */
ISProto.init = function(){
var that = this ;
This._fnItemSelectorDelegateHandler() ;
$.each(this.getOpts()["items"],function(i,item){
アイテム["インデックス"] = 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("クリック",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)、最終まとめ
(1) オブジェクト指向の考え方を用いて機能要件を合理的に分析します。
(2) プラグイン ロジックをクラスの形式で整理します。
(3) 上記の例を継続的に再構成するにはどうすればよいでしょうか?過度に設計せず、快適に使用することをお勧めします。手続き型設計とオブジェクト指向設計を組み合わせることです。
(4)、関連機能は次の記事で拡張されます。たとえば、「mode」属性は、「1」の場合にチェックボックスの複数選択モードをサポートしますが、現在はデフォルトのドロップダウン モードのみです。 。
私の記事を見てください、前のコードよりもはるかに優れていますか? 友人も、自分のプロジェクトを実行するときに、より多くのことを考え、より多くのことを実行し、コードをより合理的にするよう努めるべきです。