2012-01-31 11 views
9

イベントを使用して、Google閉鎖(GC)環境で自分のオブジェクト間で通信したいと考えています。Google閉鎖でイベントを作成する

私は2つのクラスfoobar.Bossfoobar.Employeeがあるとします。ボスは、いつ従業員がコーヒーを作ったのか、コーヒーがデカフであるかどうかを知りたがっています(彼は今週カフェインをやっています)。

GCは、これを行う手段を提供するようなクラスを用意しています(goog.events.Eventおよびgoog.events.EventTarget)。

良く知らず、私はそれがこのように働くだろうと思うだろう:

foobar.Employee.prototype.makeCoffee = function(isDecaf) 
{   
    this.coffeeMaker.putCoffeeInMachine(isDecaf); 
    this.coffeeMaker.start(); 
    var event = new goog.event.Event('COFFEE_ON', { isDecaf: isDecaf }); 
    goog.events.dispatchEvent(event); 
} 

foobar.Boss.prototype.addEmployee = function(employee) 
{ 
    ... 
    goog.events.listen(employee, 'COFFEE_ON', function(e) 
    { 
     if (e.target.isDecaf) 
     { 
      this.refillMug(); 
     } 
    }, false, this); 
    ... 
} 

これが正しいパターンですか?私はクラスによって混乱していますgoog.events.EventTarget - どのようにターゲットディスパッチイベントですか?ターゲットには何も起こりませんか?

This questionが役立ちますが、より直接的な回答は高く評価されます。

+0

http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/fx/fx.js?r=2 #582実装例 - goog.events.EventTargetから継承したものが異常です(EmployeeがEventTargetを拡張することは完全に必要ですか?) –

答えて

9

これをしばらく見ていると、実際にはEventTargetが、イベントと聴取されるエンティティを送信するエンティティというデュアルロールを演じていることを理解しました。だから1つのオプションはEmployeeを継承することですgoog.events.EventTargetしかし、私は別のルートを行っている。

最初に私は、コーヒーがカフェであるかどうかをボスに知らせる新しいイベントタイプを作成しました。

/** 
* @constructor 
* @extends {goog.events.Event} 
*/ 
foobar.CoffeeEvent = function(isDecaf) 
{ 
    goog.events.Event.call(this, 'COFFEE_ON'); 
    this.isDecaf = isDecaf; 
}; 
goog.inherits(foobar.CoffeeEvent, goog.events.Event); 

次のイベントをディスパッチするイベントリスナータイプを作成しました。

/** 
* @constructor 
* @extends {goog.events.EventTarget} 
*/ 
foobar.CoffeeEventTarget = function() 
{ 
    goog.events.EventTarget.call(this); 
}; 
goog.inherits(foobar.CoffeeEventTarget, goog.events.EventTarget); 

私はEmployeeにこのタイプのオブジェクトを追加しました。

foobar.Employee = function() 
{ 
    ... 
    this.coffeeEvents = new foobar.CoffeeEventTarget(); 
    ... 
} 

従業員がコーヒーを補充:

foobar.Employee.prototype.makeCoffee = function(isDecaf) 
{   
    this.coffeeMaker.putCoffeeInMachine(isDecaf); 
    this.coffeeMaker.start(); 
    var event = new foobar.CoffeeEvent(isDecaf); 
    this.coffeeEvents.dispatchEvent(event); 
} 

氏Bossmanは、このためにリッスンします。

foobar.Boss.prototype.addEmployee = function(employee) 
{ 
    ... 
    goog.events.listen(employee.coffeeEvents, 'COFFEE_ON', function(e) 
    { 
     if (e.isDecaf) 
     { 
      this.refillMug(); 
     } 
    }, false, this); 
    ... 
} 

イベントターゲットはCoffeeEventTargetのインスタンスになるので、これは、私に従業員がコーヒーを詰め替えを教えてくれないことに注意してください。もしあなたがEmployeeのすべてを望むなら、それをメンバーフィールドとして追加することができます。 Employeeからgoog.events.EventTargetに継承してOKだった場合は、Employeeを無料で入手できます。

+0

foobar.CoffeeEventは、ハードコードされているのではなく、おそらくタイプを受け入れるべきです。これはenumのための良い使用になります。 –

+0

まだこれを見ています。私の場合、EventTargetのサブクラス化は本当に必要ありません。 –

1

私はのEventTargetの考え方はこれです:

ボタン一つが行われるたびに、そのクリックイベントについて通知されるように登録することができ、ターゲット、です。したがって、クリックの「ターゲット」はボタンです(ボタンをクリックしてからクリックします)。ボタンがクリックされると、ボタンがクリックされたことを誰にも知らせるマウスではなく、ボタン自体がそのメッセージを送出します。あなたはダウンイベントキーをリッスンしたい場合、あなたはおそらく何気に

なぜ誰かが/でのEventTargetをサブクラス化したい必要があるだろう@ベン・フリンに育て質問にタッチし

キーが押された。どのキーが押されたかを知る方法は、イベントのkeyDownEventTargetによって送出されたオブジェクトのkeyCodeフィールドを調べることです。一方、ButtonEventTargetは、KeyCodeフィールドを持たない別のイベントオブジェクト、つまりClickEventを送出します。要約すると、EventTargetをサブクラス化する理由は、そのターゲットによってディスパッチされるイベントをリッスンしている人は、イベントがトリガーされたときにどのイベントオブジェクトがディスパッチされるかを知っているからです。

0

ここで私はそれをやります...

コーヒータイプを設定しましょう。これをさらに進めるなら、Coffeeクラスをベースにして、DecafCoffeeクラスでサブクラス化することができます。しかし、物事を単純に保つことができます。

foobar.Coffee.js

/** 
* @fileoverview Coffee class 
*/ 

goog.provide('foobar.Coffee'); 

/** 
* @constructor 
*/ 
foobar.Coffee = function(){ 
    //... 
}; 

当社のEmployeeクラスは、イベントを送出することができるようにgoog.events.EventTargetを実装する必要があります。 goog.baseまたはgoog.events.EventTarget.callという親コンストラクタを呼び出すことは、クラスが必要とする内部変数を設定することを忘れてはなりません。

foobar.Employee.js

/** 
* @fileoverview Implements the Employee class 
*/ 

goog.provide('foobar.Employee'); 
goog.require('goog.events.EventTarget'); 
goog.require('foobar.Coffee'); 

/** 
* @constructor 
*/ 
foobar.Employee = function(){ 
    // Calls the parent class (goog.events.EventTarget) 
    goog.base(this); 
}; 
goog.inherits(foobar.Employee, goog.events.EventTarget); 

/** 
* Make a coffee 
*/ 
foobar.Employee.prototype.makeCoffee = function(){ 
    // Determine what coffee type to make ... 
    // Create the coffee 
    var coffee = new foobar.Coffee(); 
    this.dispatchEvent({ 
     type: "decaf_coffee", 
     target: coffee 
    }); 
}; 

ボスクラスは、イベントをディスパッチされませんよう、特別な何かをする必要はありません。それは私たちが呼び出すことができる#drinkCoffee()メソッドが必要です。あなたが好きな場所

foobar.Boss.js

/** 
* @fileoverview Implements the Boss class 
*/ 

goog.provide('foobar.Boss'); 

/** 
* @constructor 
*/ 
foobar.Boss = function(){ 
    //... 
}; 

/** 
* Make this boss drink coffee 
* @param {foobar.Coffee} coffee The coffee to drink 
*/ 
foobar.Boss.prototype.drinkCoffee = function(coffee){ 
    //.... 
}; 

これは、あなたが実行していることでしょう主なJavaScriptコードで、あなたが置くことができ、例えばブラウザまたは独自のスクリプトでインライン展開します。

main.js

goog.require('foobar.Boss'); 
goog.require('foobar.Employee'); 
goog.require('goog.events'); 

// Jane is the boss of Sam, but we will use lower case as I typically 
// only capitalise the first letter to indicate a constructor. 
var jane = new Boss(); 
var sam = new Employee(); 

// Set up event listening 
goog.events.listen(sam, "decaf_coffee", function(e){ 
    var coffee = e.target; 
    // We've got the decaf coffee Sam made, now Jane can enjoy drinking it 
    jane.drinkCoffee(coffee); 
}, false, this); 

// Tell Sam to make a coffee 
sam.makeCoffee(); 
関連する問題