1. 개방 분석
오늘이 기사에서 우리는 무엇을 말합니까? 헤 헤헤. 그런 다음 이전 기사에서 단점을 재구성하고 이해하기 쉬운 방식으로 단계별로 분석하여 모든 사람이 단계별로 개선 할 수있었습니다. 덜 말도 안되고 요점에 도달하십시오. 먼저 이전을 검토합시다
JS 부품 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
기능 항목 선거인 (Elem, Opts) {
this.elem = elem;
this.opts = opts;
};
var isproto = itemselector.prototype;
isproto.getelem = function () {
이 this.elem;
};
isproto.getOpts = function () {
this.opts를 반환합니다.
};
/* 데이터 조작*/
ISPROTO._SETCURRENT = 함수 (현재) {
this.getOpts () [ "current"] = current;
};
isproto.getCurrentValue = function (현재) {
reture this.getOpts () [ "current"];
};
/* 데이터 조작*/
isproto.init = function () {
var that = this;
this.getOpts () [ "current"] = null; // 데이터 커서
this._setitemvalue (this.getOpts () [ "currentText"]);
var itemelem = that.getElem (). find ( ". content .items");
this.getElem (). find ( ". title div"). on ( "click", function () {
itemselem.toggle ();
});
this.getElem (). find ( ". 제목 span"). on ( "click", function () {
itemselem.toggle ();
});
$ .Each (this.getOpts () [ "항목"], function (i, item) {
항목 [ "id"] = (새 날짜 (). gettime ()). toString ();
that._render (항목);
});
};
isproto._setitemvalue = 함수 (value) {
this.getElem (). find ( ". title div"). 텍스트 (값)
};
isproto._render = function (항목) {
var that = this;
var itemelem = $ ( "<div> </div>")
.Text (항목 [ "텍스트"])
.attr ( "id", 항목 [ "id"]);
if ( "0"== 항목 [ "disabled"]) {
itemelem.on ( "클릭", function () {
var onchange = that.getOpts () [ "Change"];
that.getelem (). find ( ". content .items"). hide ();
that._setitemvalue (item [ "text"]);
that._setCurrent (항목);
onchange && onchange (항목);
})
.MouseOver (function () {
$ (this) .addclass ( "항목 호버");
})
.mouseout (function () {
$ (this) .removeClass ( "항목 호버");
});
}
또 다른{
itemelem.css ( "색상", "#ccc"). on ( "click", function () {
that.getelem (). find ( ". content .items"). hide ();
that._setitemvalue (item [ "text"]);
});
}
itemelem.appendto (this.getElem (). find ( ". content .items"));
};
효과는 아래 그림에 나와 있습니다.
a) --------운영 불가능한 상태
b) ------ 운영 가능한 상태
(ii) 아이디어를 열고 재구성하십시오
코드에서 "JS"의 구문 특성을 통해 객체 지향적 방식으로 효과적으로 구성된 코드를 보는 것은 어렵지 않지만, 이는 느슨한 프로세스 기반 조직 방법보다 훨씬 우수하지만 여전히 많은 단점을 찾을 수 있습니다.
(1) 반복이 너무 많습니다
(2) 책임의 분할은 불분명하다
(3) 프로세스가 완료되지 않았습니다
우리는 위의 점에 따라 효과적으로 리팩토링되었습니다. 먼저이 구성 요소의 요구 사항을 분류해야하며 기능 지점은 다음과 같습니다.
(1) 구성 구성 요소를 초기화합니다
코드 사본은 다음과 같습니다.
$ (function () {
var itemselector = 새 항목 선거 ($ ( "#item-selector"), {
CurrentText : "항목을 선택하십시오",
항목 : [
{{
텍스트 : "JavaScript",
가치 : "JS",
장애인 : "1"
},
{{
텍스트 : "CSS",
가치 : "CSS",
장애인 : "0"
},
{{
텍스트 : "html",
가치 : "html",
장애인 : "0"
}
],,
});
itemselector.init ();
});
이 코드는 매우 명확하고 수정이 필요하지 않지만 여러 옵션을 지원하기 위해 구성 항목 "모드"를 추가하는 등의 구성을 기반으로 함수를 확장 할 수 있습니다. 예를 들어 : "확인란 확인 모드".
다음은 다음과 같이 초기화 로직을 완료하는 것입니다.
코드 사본은 다음과 같습니다.
isproto.init = function () {
var that = this;
this.getOpts () [ "current"] = null; // 데이터 커서
this._setitemvalue (this.getOpts () [ "currentText"]);
var itemelem = that.getElem (). find ( ". content .items");
this.getElem (). find ( ". title div"). on ( "click", function () {
itemselem.toggle ();
});
this.getElem (). find ( ". 제목 span"). on ( "click", function () {
itemselem.toggle ();
});
$ .Each (this.getOpts () [ "항목"], function (i, item) {
항목 [ "id"] = (새 날짜 (). gettime ()). toString ();
that._render (항목);
});
};
이 코드에는 많은 문제, 불분명 한 책임이 있으며 초기화 로직에는 기능적 지점의 상세한 구현이 포함되어 있습니다.
렌더링 코드를 계속보십시오.
코드 사본은 다음과 같습니다.
isproto._render = function (항목) {
var that = this;
var itemelem = $ ( "<div> </div>")
.Text (항목 [ "텍스트"])
.attr ( "id", 항목 [ "id"]);
if ( "0"== 항목 [ "disabled"]) {
itemelem.on ( "클릭", function () {
var onchange = that.getOpts () [ "Change"];
that.getelem (). find ( ". content .items"). hide ();
that._setitemvalue (item [ "text"]);
that._setCurrent (항목);
onchange && onchange (항목);
})
.MouseOver (function () {
$ (this) .addclass ( "항목 호버");
})
.mouseout (function () {
$ (this) .removeClass ( "항목 호버");
});
}
또 다른{
itemelem.css ( "색상", "#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 () {
// 여기에 코드를 넣으십시오!
};
세 번째 단계는 데이터 작업 인터페이스를 설정하는 것입니다.
코드 사본은 다음과 같습니다.
isproto._setCurrent = function () {
// 여기에 코드를 넣으십시오!
};
isproto._getCurrent = function () {
// 여기에 코드를 넣으십시오!
};
아래에 언급 된 아이디어 일뿐입니다.
(iii), 전체 코드는 학습을위한 것입니다.이 코드는 테스트되었습니다.
코드 사본은 다음과 같습니다.
기능 항목 선거인 (Elem, Opts) {
this.elem = elem;
this.opts = opts;
이 .current = -1; // 데이터 커서
};
var isproto = itemselector.prototype;
/* getter api*/
isproto.getelem = function () {
이 this.elem;
};
isproto.getOpts = function () {
this.opts를 반환합니다.
};
isproto._getCurrent = function () {
이를 반환하십시오.
};
/* getter api*/
/* 데이터 조작*/
ISPROTO._SETCURRENT = 함수 (현재) {
this.current = current;
};
isproto._setitemtext = function (text) {
this.getElem (). find ( ". title div"). 텍스트 (텍스트);
};
/* 데이터 조작*/
/ * 2015 년 업데이트 1/31 23:38 */
isproto._fntriggerHandler = 함수 (색인, 텍스트, 값) {
if (this._isdisabled (value)) {
색인 = -1;
text = this.getOpts () [ "currentText"];
}
this._SetItemText (텍스트);
this._setCurrent (색인);
this.getElem (). find ( ". content .items"). hide ();
};
isproto._addorremoveclass = function (elem, classname, addis) {
if (addis) {
elem.addclass (className);
}
또 다른{
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)? 사실 : 거짓;
};
/ * 2015 년 업데이트 1/31 23:38 */
isproto.init = function () {
var that = this;
this._fnitemselectordeGateHandler ();
$ .Each (this.getOpts () [ "항목"], function (i, item) {
항목 [ "index"] = i;
that._render (항목);
});
this._fntriggerHandler (this._getCurrent (), this.getOpts () [ "currentText"], "1");
};
isproto._render = function (항목) {
var that = this;
var itemelem = $ ( "<div> </div>"). text (item [ "text"]). attr ( "id", item [ "index"]);
var activeclass = ( "0"== 항목 [ "disabled"])? "항목-호버": "아이템 장애인-호버";
itemelem.on ( "클릭", function () {
that._fntriggerHandler (항목 [ "index"], 항목 [ "text"], 항목 [ "disabled"]);
})
.MouseOver (function () {
that._addorremoveclass ($ (this), activeclass, true);
})
.mouseout (function () {
that._addorremoveclass ($ (this), activeclass, false);
});
itemelem.appendto (this.getElem (). find ( ". content .items"));
};
(iv), 최종 요약
(1) 객체 지향적 사고 방식에서 기능적 요구 사항에 대한 합리적인 분석.
(2), 플러그인 로직을 수업 방식으로 구성하십시오.
(3) 위의 예를 지속적으로 재구성하는데,이를 합리적으로 재구성하는 방법은 무엇입니까? 과도하게 설계하지 마십시오. 권장 방법은 프로세스 설계와 객체 지향적 사고 설계를 결합하는 것입니다.
(4) 다음 기사는 속성 "모드"와 같은 관련 기능을 확장합니다. "1"인 경우 CheckBox Multi-Select 모드를 지원하지만 이제는 기본 드롭 다운 모드입니다.
내 기사를 살펴보면 이전 코드보다 훨씬 낫습니까? 친구들은 스스로 생각하고 더 많은 프로젝트를 수행하고 자신의 코드를 더 합리적으로 만들어야합니다.