7

与えられた: リアクティブ拡張機能のドラッグ アンド ドロップの例では、ドロップ イベントだけをどのようにサブスクライブしますか?

「完了」コールバックをサブスクライブするようにコードを変更しましたが、完了しません。

    (function (global) {

    function main () {
        var dragTarget = document.getElementById('dragTarget');
        var $dragTarget = $(dragTarget);

        // Get the three major events
        var mouseup  = Rx.Observable.fromEvent(document, 'mouseup');
        var mousemove = Rx.Observable.fromEvent(document,    'mousemove');
        var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');

        var mousedrag = mousedown
            .filter(function(md){                   
                //console.log(md.offsetX + ", " + md.offsetY);
                return  md.offsetX <= 100
                        ||
                        md.offsetY <= 100;
            })
            .flatMap(function (md) {

                // calculate offsets when mouse down
                var startX = md.offsetX, startY = md.offsetY;

                // Calculate delta with mousemove until mouseup
                return mousemove.map(function (mm) {
                    mm.preventDefault();

                    return {
                        left: mm.clientX - startX,
                        top: mm.clientY - startY
                    };
                }).takeUntil(mouseup);
            });


        // Update position
        var subscription = mousedrag.subscribe(
        function (pos) {                    
            dragTarget.style.top = pos.top + 'px';
            dragTarget.style.left = pos.left + 'px';
        },
        function(errorToIgnore) {},
        function() {    alert('drop');});

    }

    main();

}(window));

マウスイベントから作成されたものなどのホットオブザーバブルは決して「完了」しないことを読みました。これは正しいです?それ以外の場合、「ドロップ」でコールバックを取得するにはどうすればよいですか?

4

2 に答える 2

6

このようなものがうまくいくはずです。

(function (global) {

    function main () {
        var dragTarget = document.getElementById('dragTarget');

        // Get the three major events
        var mouseup = Rx.Observable.fromEvent(document, 'mouseup');
        var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
        var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown');

        var drop = mousedown
                .selectMany(
                    Rx.Observable
                        .concat(
                            [
                                mousemove.take(1).ignoreElements(),
                                mouseup.take(1)
                            ]
                        )
                );
    }

    main();

}(window));

編集:

オブザーバブルを複数の値を生成し、完了またはエラーの可能性がある非同期関数と考えると、完了イベントが 1 つしかないことがすぐにわかります。

複数の関数の作成を開始すると、その関数の内部に複数の関数が含まれていても、最も外側の関数は 1 回しか完了しません。したがって、「完了」の総数が 3 であっても、最も外側の関数は 1 回しか完了しません。

基本的に、ドラッグが完了するたびに最も外側の関数が値を返すと想定される場合、実際にそれを行う方法が必要です。ドラッグの完了を最も外側のオブザーバブルの「onNext」イベントに変換する必要があります。

あなたがそれを行うことができる方法はすべて、あなたが望むものを手に入れることができます. おそらく、最も外側の関数が返す唯一の種類のイベントであるか、ドラッグの開始と移動も返す可能性がありますが、ドラッグの完了を返す限り、必要なものが得られます (必要な場合でも)後でフィルタリングします)。

上記の例は、ドラッグ ドロップを最も外側のオブザーバブルに返す 1 つの方法にすぎません。

于 2014-06-13T22:21:52.993 に答える