PrototypeのカスタムイベントはDOMイベントに関連付けられているため、DOMを何ら使用せずにクラスやインスタンスでイベントを発生させる方法はありません。つまり、Prototypeのカスタムイベントを使ってカスタムイベントをクラスに追加することができます。
数年前Tobie Langelはa way of adding custom events to Prototype classesを共有しました。このアプローチの欠点は、これらのイベントが発生し、クラス・レベルで観測されることです。つまり、あるインスタンスによって起動されたイベントが、そのクラスのインスタンスをすべてのリスナーが検出したことを意味します。
私は、インスタンスを個別に観察できるようにするTobieのアプローチにいくつかの簡単な変更を加えました。ここでは、Class.create
のクロージャを使用して、クラスのインスタンスごとにプライベートイベント名前空間を作成しています。カウンタは、クラスの新しいインスタンスが作成されるたびにインクリメントされます。
var Observable = Class.create({
fire : function(eventName, data){
document.fire(this._namespace + ':' + eventName, data);
},
observe : function(eventName, callback){
document.observe(this._namespace + ':' + eventName, callback);
},
stopObserving : function(eventName, callback) {
// Probably wise to also implement this...
}
});
var Widget = (function(){
var namespace = 'widget', counter = 0;
return Class.create(Observable, {
initialize : function(){
this._namespace = namespace + ':' + counter++;
},
complete : function(){
this.fire('complete');
}
});
}());
var myWidget = new Widget();
myWidget.observe('complete', function(e){
// Callback executed when 'complete' is fired on myWidget.
});