0

Reactive ExtensionsJavaScriptは初めてです。誰かが次のコードを緩めるのを手伝ってくれますか? これはMatthew Podwysocki の JavaScript に対する Reactive Extensions の紹介 からのものです。

<html>
<head>
 <title>Learning ReactiveExtensions</title>
 <!--scripts-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="rx.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function() {
var mouseDragMe = $("#mouseDragMe").context;

var mouseMove = Rx.Observable.FromHtmlEvent(mouseDragMe, "mousemove");
var mouseUp = Rx.Observable.FromHtmlEvent(mouseDragMe, "mouseup");
var mouseDown = Rx.Observable.FromHtmlEvent(mouseDragMe, "mousedown");

    var mouseMoves = mouseMove
.Skip(1)
.Zip(mouseMove, function(left, right) {
    return { x1 : left.clientX,
             y1 : left.clientY,
             x2 : right.clientX,
             y2 : right.clientY };
});

    var mouseDrags = mouseDown.SelectMany(function(md) {
return mouseMoves.TakeUntil(mouseUp);

    mouseDrags.Subscribe(function(mouseEvents) {
$("#results").html(
    "Old (X: " + mouseEvents.x1 + " Y: " + mouseEvents.y1 + ") " +
    "New (X: " + mouseEvents.x2 + " Y: " + mouseEvents.y2 + ")");
});
});                     
});
</script>
</head>
<body>
<div id="mouseDragMe" style="border:solid 1px red;">
    i am a rx newbie
</div>
</body>
</html>
4

1 に答える 1

3

このあたりの記述があります。最初の Rx アプリケーションの作成に関するこのビデオを見ることをお勧めします。コードは C# ですが、プログラミング言語に関係なく概念はまったく同じです。

基本的に3つのことを理解したい

  1. 一連のイベントをシーケンスとして概念化する。配列が空間内のデータのシーケンスであるのと同様に、イベントは時間内 (または移動中) のデータのシーケンスと考えることができます。
  2. 演算子 (つまりSkipZipSelectManyおよびTakeUntil)
  3. サブスクリプションのセマンティクス

このシナリオでは、3 つのソース シーケンスがあります。mouseMovemouseUpおよびmouseDown

mouseMoveシーケンスは、マウスが移動するたびにマウス座標の値をプッシュします。たとえば、マウスが画面の左上隅から開始し、斜め下に移動してからまっすぐ横に移動した場合、シーケンスで発行された{0,0}{10,10}、などの値が表示される場合があります。{20,10}

が公開する値は興味深いものではなくmouseUpmouseDown公開された時点だけが興味深いものです。

「ドラッグ」の実際の問題では、マウス ボタンが押されたときと、マウスが押されたときの位置とボタンが離されたときの位置のデルタを知る必要があります。これらの位置のデルタを取得する方法は、最終的な位置の値を取り、元の位置の値を差し引くことです。動きをアニメートできるように、中間のデルタ値をすべて取得できればさらに良いでしょう。上記のシーケンスを使用すると、動きのデルタを取得するために、元のシーケンスと 1 つずれたシーケンスが必要になります

Original { 0, 0}, {10,10}, {20,10}  
offby1   {10,10}, {20,10}  

これにより、デルタを計算して (場所だけでなく) 動きを把握することができます。

Original { 0, 0}, {10,10}, {20,10}
offby1   {10,10}, {20,10}
delta    {10,10}, {10, 0}

Rx でこれを実現する方法は、最初にSkip(1)1 つの値をスキップするために使用します。これにより、offby1シーケンスが作成されます。次に、値をペアで結合します。Zip関数はこれを提供します (詳細については、Combining sequence with Zip に関する私のブログ投稿を参照してください)。

上記のコードを書き直すことができます

var mouseMoves = mouseMove
.Skip(1)
.Zip(mouseMove, function(left, right) {
    return { x1 : left.clientX,
             y1 : left.clientY,
             x2 : right.clientX,
             y2 : right.clientY };
});

することが

var offby1 = mouseMove.Skip(1);
var mouseMoves = offby1.Zip(mouseMove, function(left, right) {
    return { x1 : left.clientX,
             y1 : left.clientY,
             x2 : right.clientX,
             y2 : right.clientY };
});

ペアを取得したら、 の簡単な計算を適用する必要がありますnewValue-OldValue=delta。これにより、実質的に移動シーケンスであるデルタ シーケンスが得られます。

var offby1 = mouseMove.Skip(1);
var mouseMoves = offby1.Zip(mouseMove, function(current, last) {
    return { x : current.clientX-last.clientX,
             y : current.clientY-last.clientY };
});

ここで、マウスが押されたときにのみ値を取得したいと考えています。これを行うには、SelectMany演算子を使用します。これは、ソースからの各値について、このソースから 0 個以上の値を取得することを示しています。私たちの場合、イベントが発生するたびに、mouseDownすべてのデルタ イベントを取得したいと考えています (as mouseMoves)。

var mouseDrags = mouseDown.SelectMany(function(md) { return mouseMoves;});

mouseUpただし、対応するイベントが発生するまで受信し続けたいだけです。これを行うためにTakeUntilmouseUpイベントは値を生成します。

var mouseDrags = mouseDown.SelectMany(function(md) {
  return mouseMoves.TakeUntil(mouseUp);
});

このすべての配管が完了したので、通常、これらの動きを UI 要素の位置/マージン/オフセットに適用します。例に表示されていますが、値を出力するだけです。

于 2012-09-19T12:48:47.397 に答える