ここでのインターフェイスの意味は、Observable が実際には Extjs の多数のコンポーネントがこのクラスから継承するということです。このクラスは、addEvents、addlistener、fireEvent などのいくつかの基本メソッドを提供します。
この記事では、extjs コンポーネントを使用してイベントに応答する方法を紹介するのではなく、Extjs イベントの実装原則をいくつか紹介します。 Extjs フレームワーク全体はオブジェクト指向で開発されているため、JavaScript の継承を理解することも重要です。前回の記事はこの記事の準備でもありました。さらに、ブログ パークには、よく書かれたシリーズ JavaScript 継承の詳細な説明 があり、主に Douglas Crockford による 2 つの記事に基づいています。 実際、継承を実装するための原則は似ているため、参照として読むことができます。 Extjs によって継承された関数は非常にコアな関数 Ext.extend です。extend メソッドには 2 つのリファクタリングされたバージョンがあり、最初のものは extend(Function superclass, Object overrides) です。 2 番目のバージョンは extend(Function subclass, Function superclass,Object overrides): Function です。2 番目のバージョンはサブクラスに基づいています。スーパークラスはスーパークラスのコンストラクターであり、オーバーライドはオブジェクトであり、内部の属性は親クラスの属性をオーバーライドします。親クラスを継承するサブクラスには、親クラスのプロトタイプ内のすべてのメソッドが含まれます。また、サブクラスは親クラスのメソッドをオーバーライドすることができます (オーバーライド)。また、サブクラスの各オブジェクトも親クラスのメソッドをオーバーライドできます。実際、この関数には何の効果もないと思います。もちろん、extjs の目的は、プロトタイプという魔法のようなものを完全に保護して、プログラマが他の言語と同じように JavaScript を処理できるようにすることです。もちろん、そうであっても、その継承は通常の継承とは多少異なります。まず、例を見てみましょう。
コードをコピーします。 🎜 > コードは次のとおりです。 person = function(name) { this.name = name;
this.fn = function() {alert('私は人間です ') };
}
person.prototype.print=function(){alert('私は人間です');}
person.prototype.showAge = function() {alert ('私は 0 歳以上です'); }
person.prototype.showName = function() {alert('Show Name:' this.name) };
var per = new Person('Tom') ;
per.showName(); サブクラス: Student = function(id) {
this.id = id;
Student.prototype.showID = function() { ); } //サブクラスのメソッド
継承:
Extend(Student, Person); !!結果はありません! stu には名前の定義がありません stu.fn(); !!結果がありません stu.showID(); !!!まだ結果がありません この時点で、いくつかの違いが見つかりました: 親クラスのコンストラクターの内容は継承されません. の場合、親クラスのコンストラクターは呼び出されず、サブクラス (プロトタイプ内の) の既存のメソッドも失われます。読み続けて、Ext.extend の下のコードを次のコードに置き換えます:
コードをコピーします
ここでの関数はすべて、親クラスの実行メソッドであり、stu. print は .override で指定されたメソッドを実行する stu であり、stu2 は Student.override で指定されたメソッドを実行します。この時点で、extend がどのように実装されるかを大まかに推測できます。以下の実際のソース コードを見てみましょう。このメソッドは Ext.js にあります。コードとコメントは次のとおりです。extend : function(){
Copy code
コードは次のとおりです:
// inline overrides
var io = function(o){ //このメソッドは一見しただけではわかりません。次の io が割り当てられます。 sbp.override 、つまりサブクラスのプロトタイプ
for(var m in o){ //各サブクラス オブジェクトのオーバーライドは、このメソッドを指します。サブクラス オブジェクトが override を呼び出す場合、これは のオブジェクトです。サブクラス。つまり、
this[m] = o[m]; //上記の例で stu.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, argument);};これを読んでください...
}
var F = function(){},
sbp,
spp = sp.prototype;
F.prototype = spp; /F は親です。 クラスの「クリーン」コピー。クリーンとは、親クラスのコンストラクター内で定義されたプロパティを引き継がないことを意味します。 //たとえば、 Person=function() // {this.privateFn=new function{ some code go here}} // この privateFn はサブクラスには見えないため、コンストラクターでこれを使用して定義された属性は、次のプライベート変数と同等です。クラス。
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);} //複数のサブクラスを実装するための extend メソッドを提供します。継承
return sb; // サブクラスを返します。
};
}();
以下は、インライン オーバーライドと比較して比較的明確な、変更された prototype: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.addEvents('onFindOdd');
}
Ext.extend(Odder, Ext.util.Observable, { run:
function() {
for (var i = this.min; i < this.max; i ) {
if (i % 2 != 0) {
this.fireEvent ('onFindOdd ',i);
}
}
});
var p = new Odder(4, 8); ,function(n){alert(n);});
p.run();
Odder は、コンストラクターを介して範囲を渡し、範囲内のすべての奇数を検索し、奇数が見つかるたびにイベントをトリガーするクラスです。これにイベント ハンドラーを追加して、見つかった奇数を警告します。 ここでのイベント ハンドラーのパラメーターはプログラマによってのみ一貫性を保つことができ、デリゲートほど厳密に型指定されないことに注意してください。
公式 Web サイトの例は使用していないことに注意してください:
Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this. addEvents({
" fired" : true,
"quit" : true
});
// 構成されたリスナーを *this* オブジェクトにコピーして、基本クラスの
// コンストラクターがそれらを追加します。
this.listeners = config.listeners;
// スーパークラス コンストラクターを呼び出して構築プロセスを完了します。 >}
}) ;これは次のように使用できます:
var newEmployee = new Employee({
name:employeeName,
listeners: {
quit:function() {
// デフォルトでは、「this」はイベントを起動したオブジェクトになります。
alert(this.name " has quit!")
}
}
i 公式 Web サイトの例に記事があると思います。そのオーバーロードされた項目には、親クラスのコンストラクターがオーバーロードされ、サブクラスがこれを呼び出すという印象を与えます。実際、これは、JavaScript 自体の動作を変更するものではありません。これは、私が理解できなかった、上でマークしたコードの数行に関連しています。詳しい議論は次回に。