여기서 인터페이스의 의미는 Observable이 실제로 추상 클래스로 작동한다는 것입니다. Extjs의 많은 구성 요소는 이 클래스에서 상속됩니다. 이 클래스는 addEvents, addlistener, fireEvent 등과 같은 몇 가지 기본 메소드를 제공합니다.
이 글에서는 extjs 컴포넌트를 사용하여 이벤트에 응답하는 방법을 소개하지 않고 Extjs 이벤트의 몇 가지 구현 원칙을 소개합니다. Extjs 프레임워크 전체가 객체지향적으로 개발되었기 때문에 Javascript에서의 상속을 이해하는 것도 중요합니다. 이전 글도 이 글을 위한 준비물이었습니다. 그 밖에도 블로그파크에 JavaScript 상속에 대한 자세한 설명이 잘 쓰여진 시리즈가 있습니다. 그는 주로 Douglas Crockford의 두 글을 기반으로 하고 있습니다. 실제로 상속을 구현하는 원칙은 유사하므로 참고용으로 읽어보시면 됩니다. Extjs가 상속한 함수는 매우 핵심적인 함수인 Ext.extend입니다. 확장 메소드에는 두 개의 리팩터링 버전이 있습니다. 첫 번째 버전은 두 개의 매개변수를 허용하고, 첫 번째 버전은 확장(Function superclass, Object overrides)입니다. 두 번째 버전은 Extension(Function subclass, Function superclass,Object overrides): Function입니다. 두 번째 버전은 하위 클래스를 기반으로 합니다. Superclass는 슈퍼클래스의 생성자이고 overrides는 객체이며 내부 속성은 상위 클래스의 속성을 재정의하기 위한 것입니다. 상위 클래스를 상속하는 하위 클래스에는 상위 클래스의 프로토타입에 있는 모든 메서드가 포함됩니다. 그리고 하위 클래스는 상위 클래스의 메서드를 재정의(override)할 수 있습니다. 또한 하위 클래스의 각 객체도 상위 클래스의 메서드를 재정의할 수 있습니다. 사실 이 함수는 프로토타입을 수정하는 것과 같은 효과가 있다고 생각합니다. 물론 extjs의 목적은 프로토타입의 마법적인 것을 완전히 보호하여 프로그래머가 다른 언어처럼 Javascript를 처리할 수 있도록 하는 것입니다. 물론, 그럼에도 불구하고 그 상속은 여전히 일반적인 상속과 다소 다릅니다. 먼저 Person 클래스를 준비하세요.
stu.showName(); stu에는 이름 stu.fn();에 대한 정의가 없습니다. !!결과가 없습니다. stu.showID(); 여전히 결과가 없습니다. 이 시점에서 우리는 몇 가지 차이점을 발견했습니다. 상위 클래스의 생성자에 있는 내용은 상속되지 않습니다. . , 상위 클래스의 생성자는 호출되지 않으며 하위 클래스의 기존 메서드(프로토타입)도 손실됩니다! 계속해서 읽고 Ext.extend 아래의 코드를
Student.override({ print: function() { Alert('저는 학생입니다'); } }); { print : function() { Alert('나는 나쁜 학생이지만 다른 사람에게 영향을 주지는 않습니다') } }); >var stu2 = new Student();
stu2.print();
여기의 함수는 모두 예상대로 출력될 수 있습니다. showAge는 상위 클래스의 실행 메소드입니다. print는 stu .override에 지정된 메서드를 실행하는 반면 stu2는 Student.override에 지정된 메서드를 실행합니다. 이 시점에서 우리는 확장이 어떻게 구현되는지 대략적으로 추측할 수 있습니다. 아래에서 실제 소스 코드를 살펴보겠습니다. 이 메서드는 Ext.js에 있습니다. 코드와 설명은 다음과 같습니다. 🎜>
코드는 다음과 같습니다.
// 인라인 재정의
var io = function(o){ //이 메소드만 보면 무엇인지 알 수 없습니다. 다음 io가 할당됩니다. sbp.override, 즉 하위 클래스의 프로토타입
for(var m in o){ //각 하위 클래스 객체의 재정의는 이 메서드를 가리킵니다. 하위 클래스 객체가 재정의를 호출하면 이것이 의 객체입니다. 서브클래스. 즉,
this[m] = o[m]; //위 예시에서 stu.override가 보여준 효과는 현재 객체에만 유효합니다. 여기에서 override는 전통적인 의미의 재정의일 뿐만 아니라
} // 새 메서드를 추가하는 데에도 사용할 수 있음을 알 수 있습니다.
};
var oc = Object.prototype.constructor;
return function(sb, sp, overrides){
if(Ext.isObject(sp)){ // 현재 사용 중인 리팩토링 기능의 버전을 감지합니다. sp가 실제로 재정의되는 경우 변수의 실제 의미가 해당 이름과 일치하도록 일부 대체를 수행합니다.
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, 인수);}; 읽어보세요...
}
var F = function(){},
sbp,
spp = sp.prototype
F.prototype = spp; /F는 부모입니다. 클래스의 "깨끗한" 복사본은 부모 클래스의 생성자 내부에 정의된 속성을 가져오지 않는다는 의미입니다. //예를 들어 Person=function() // {this.privateFn=new function{ some code goes here}} //그러면 이 privateFn은 하위 클래스에 표시되지 않으므로 생성자에서 이것을 사용하여 정의된 속성은 다음의 Private 변수와 동일합니다. 수업.
sbp = sb.prototype = new F(); //상속의 핵심 단계인 상위 클래스의 프로토타입으로 하위 클래스의 프로토타입을 설정합니다. sbp.constructor=sb; //올바른 생성자 포인터 설정, JavaScript 상속 세부정보 참조
sb.superclass=spp; //상위 클래스 설정
if(spp.constructor == oc){ //Didn' 읽지 마세요 알겠습니다..., 이건 뭐죠? 조언 좀 부탁드립니다
spp.constructor=sp;
}
sb.override = function(o){ //서브클래스의 재작성 방법, 이 재작성 방법은 함수의 재작성 방법입니다. 프로토타입을 수정합니다.
Ext.override(sb, o); //끝을 보세요.
};
sbp.superclass = sbp.supr = (function(){ //프로토타입의 상위 클래스 설정
return spp;
})
sbp.override = io ; // 하위 클래스의 프로토타입에 재정의 메서드를 제공하여 단일 엔터티를 재정의하고 엔터티 개체를 수정합니다. 위의 sb 재정의와의 차이점에 유의하세요.
Ext.override(sb, overrides); //다시 작성
sb.extend = function(o){return Ext.extend(sb, o);} //다중 구현을 위해 하위 클래스에 확장 메소드 제공 상속
return sb; //하위 클래스를 반환합니다.
};
}();
다음은 Ext.override의 코드로, 인라인 재정의에 비해 수정된 프로토타입입니다.
function(origclass, overrides){
if(overrides) {
var p = origclass.prototype;
Ext.apply(p, overrides)
if(Ext.isIE && overrides.hasOwnProperty('toString')){ // 무엇 이거요? IE의 특별한 점은 무엇입니까?
p.toString = overrides.toString;
}
}
}
이제 공식적으로 Extjs의 이벤트 모델을 소개할 수 있습니다. 다른 언어의 이벤트와 마찬가지로 먼저 클래스에 대한 이벤트를 정의해야 합니다. 다른 언어(예: C#)의 이벤트에는 일반적으로 이벤트 유형이 실제로 대리자의 배열로 간주될 수 있습니다. , 대리자는 실제로 함수입니다. Add 시간 리스너(리스너)는 대리자 배열에 대리자(함수)를 추가하려고 합니다. 소위 트리거 이벤트는 배열의 모든 함수를 실행하는 것입니다. Javascript는 유사하지만 Javascript의 기능은 해당 언어보다 훨씬 강력하고 유연하므로 이벤트 유형이 필요하지 않습니다. Javascript 이벤트는 문자열처럼 보입니다(내부적으로 배열도 유지해야 함). Observale.addEvents 메서드를 통해 이벤트를 추가하고, Observale.fireEvent를 통해 이벤트를 트리거하고, Observale.addListner를 통해 이벤트 리스너를 추가할 수 있습니다. 다음은 거의 의미가 없지만 문제를 보여주는 예입니다.
Odder = function(min, max) {
this.min = min;
this.max = max;
this.addEvents('onFindOdd')
}
Ext.extend(Odder, Ext.util.Observable, { 실행:
function() {
for (var i = this.min; i < this.max; i ) {
if (i % 2 != 0) {
this.fireEvent ('onFindOdd',i);
}
}
})
var p = new Odder(4, 8)
p.addListener('onFindOdd' ,function(n){alert(n);})
p.run()
Odder는 생성자를 통해 범위를 전달한 다음 범위에 있는 모든 홀수를 검색하고 홀수를 찾을 때마다 이벤트를 트리거하는 클래스입니다. 발견된 홀수에 대해 경고하기 위해 이벤트 핸들러를 추가합니다. 여기서 이벤트 핸들러의 매개변수는 프로그래머에 의해서만 일관성을 유지할 수 있다는 점에 유의해야 합니다. 이는 대리자만큼 강력하게 형식화되지 않습니다.
공식 웹사이트의 예제를 사용하지 않았습니다.
Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this. addEvents({
" Fired" : true,
"quit" : true
});
// 기본 클래스의
// 생성자가 이를 추가합니다.
this.listeners = config.listeners;
// 생성 프로세스를 완료하려면 슈퍼클래스 생성자를 호출하세요.
}
}) ;이것은 다음과 같이 사용될 수 있습니다:
var newEmployee = new Employee({
name: EmployeeName,
listeners: {
quit: function() {
// 기본적으로 "this"는 이벤트를 실행한 개체입니다.
alert(this.name " has quit!")
}
});
공식 웹사이트의 예제에 기사가 있는 것 같아요. 해당 항목의 오버로드된 항목에 생성자 속성이 포함되어 있는데, 이는 상위 클래스의 생성자가 오버로드된 것처럼 보이며, 그러면 하위 클래스가 이를 호출합니다. 실제로는 그렇지 않습니다. 이는 Javascript 자체의 동작을 변경하지만 위에서 표시한 몇 줄의 코드와 관련이 있습니다. 다음 시간에 더 많은 토론을 해보세요.