1

ビデオを囲むコンポーネントがあります: <div class="component"><video src="..." /></div>.

ここで、再生の状態を 2 つの方法で管理したいと考えています。

  1. ネイティブの再生/一時停止ボタンをクリックして変更できる再生状態をリッスンし、それを操作します (コンポーネント レイアウトの変更、他のコンポーネントへの通知など)。

  2. Lets sayを介して外部から手動で再生をトリガーしますmyComponent.playContent()

これを正しく管理する方法がわかりません。たとえば、ユーザーがネイティブ ビデオ コントロールをクリックすると、playイベントがディスパッチされます。myComponent.playContent()どの呼び出しを手動で呼び出すとdomVideo.play()playイベントもディスパッチされるため、イベントをリッスンするだけplayでは、混乱したり、2 回呼び出されたりします。

問題は、ここに 2 つの異なるものが混在していることです。

まず、再生開始は、ユーザーがネイティブ コントロールをクリックすることでトリガーできます。その場合、イベントをキャッチして、あらゆる種類の操作を実行したいと考えています。これは、典型的な「バブリング」のボトムアップ フローです。

第二に、プログラム (通常はコンポーネント ) は「トップダウン」の方法で再生をトリガーしたいと考えています。ここでは、発生したイベントを区別して、ユーザーが作成した再生イベントとして扱わないようにしたいと考えています。

ExtJS のタブ パネルのタブ変更イベント (tabchangeイベント ) など、この問題が何度も発生しましたが、イベント ベースのプログラミング パラダイムでこれに対処する方法がわかりません。

一般的な解決策または正しいアプローチを探しています。ネイティブ DOM イベントだけではありません。YT.Player同じモデルを持つ独自のイベントを持つ (YouTube プレーヤー) オブジェクトがあり、同じ問題に苦しんでいます。

編集:いくつかのトリックsetTimeoutとキャンセルは可能ですが、それは避けたいです。

4

1 に答える 1

0

DOMの詳細についてはわかりませんが、クライアント側のイベントベースのランタイム/プログラミングモデルでもあるFlex /FlashPlayerでどのように機能するかを説明します。

それでは、コンポーネントC(たとえば、例のビデオプレーヤー)とアプリケーションA(サブアプリケーション、アプリケーションモジュールなど、単にアプリケーションと呼びましょう)を含むアプリケーションAを用意しましょう。

コンポーネントのパブリックAPIは次のようなものです。

component VideoPlayer
    function play()
    event playStateChange

2つの状況について説明します。1つはMVCフレームワークがない場合(「ベアボーン」ソリューション)、もう1つはMVCフレームワークが配置されている場合です。

1)MVCフレームワークなし

アプリケーションはコンポーネントへの参照を持ち、どこかで次のようなものを呼び出す必要があります。

videoPlayer.addEventListener("playStateChange", function() {...})

VideoPlayerで再生を開始する必要がある場合は、

videoPlayer.play();

単純。

(質問の下部に記載されている問題、つまり、play()を呼び出すと同じイベントが再度ディスパッチされる理由がわかりません。Flexでは、プログラマーは明示的にそれを行う必要があり、それは間違いである可能性があります。もちろんです。必要に応じて別の名前のイベントをディスパッチすることは理にかなっているかもしれませんが、それは別のことです。)

2)MVCフレームワークを使用

Flexアプリケーションは通常、非常に大きく、個別の画面、コンテンツペイン、コンテナ、コンポーネントなどの階層が深くネストされているため、アプリケーションがアプリケーション内のすべてのコンポーネントを直接参照することは現実的ではない場合があります。

したがって、MVCフレームワーク(正しく名前が付けられていませんが、それは脇に置いておきましょう...)は通常、アプリケーションのさまざまな部分が相互に通信できる中央イベントバスを提供します。したがって、このフレームワークを配置すると、アプリケーション内の任意のコードで次のようなことができます。

eventBus.dispatchEvent("globalPlayEvent")

コンポーネント(VideoPlayer)は、インスタンス化中に次のようなことを行います。

eventBus.addEventListener("globalPlayEvent", function() {
    play();
}

反対方向の通信も同様です。コンポーネントは、ディスパッチされたグローバルイベント/イベントバスに「playStateChange」をディスパッチするだけで、関心のある人は誰でもそれを処理できます。このモデルでは、私が得意とするイベントバブリングに依存しません。

これはあなたの質問に答えますか?

于 2012-04-26T14:23:47.987 に答える