React-dnd: 複数の要素のドラッグをサポート

作成日 2014年10月25日  ·  30コメント  ·  ソース: react-dnd/react-dnd

ネイティブのドラッグアンドドロップでは実装が難しい一般的なパターンがあります。それは、複数の要素をドラッグすることです。 選択の仕組みはアプリごとに異なる場合がありますが(cmd +クリック、チェックボックス、事前定義されたグループ)、少なくともこのシナリオをサポートできるようにするとよいでしょう。

screen shot 2014-10-26 at 1 07 07

複数のドラッグされたアイテムはDOMの兄弟ではない可能性があり、 setDragImage(element, x, y)はかなり正気ではなく、改善されていないため、ドラッグプレビューで複数の要素を一度にレンダリングしようとしても負担はありません。

「複数の」ドラッグプレビューを表示できない場合、このシナリオの実装をどのように支援できますか?

ある意味で、このシナリオはすでに可能です。消費者は、選択した要素を手動で追跡し、 dragPreviewをある種の一般的なプレースホルダーImageし、(ビジネスに関する限り)ドロップに適切に対応できます。ロジックが関係している)いくつかの要素。

ただし、現在、ドラッグされているグループの一部であることを1つの要素が認識するためのサポートされている方法はありません。 react-dndの観点から、何かをドラッグすると、このコンポーネントはgetDragState(type).isDragging = true取得しますが、他のコンポーネントは取得しません。 アプリの観点から、複数選択をサポートしている場合は、論理的に「選択された」すべてのアイテムが、実際には1つだけが「DOMドラッグ」されている場合でも、ドラッグされていることを認識できるようにします。

必要なのは、コンポーネントがreact-dndに次のように伝える方法です。「ねえ、 onDragStartは別のコンポーネントによって受信されましたが、自分もドラッグされているふりをして、 getDragState(type)を持っています。 getDragState(type) getDragState(type)ミラーリングし、 endDrag(didDrop)呼び出して、自分の作業を実行できるようにします。」

コンポーネントはどのようにそれにオプトインしますか?

design decisions

最も参考になるコメント

誰かが興味を持っているなら、私は複数のドラッグ/グリッドビューを実装しました: https
cmd / ctrlキーとShiftキーを使用して複数のアイテムを選択し、グリッド上でドラッグして任意の場所に挿入できます。

これはまだデモですが、コードをもう少し抽象化して、後でコンポーネントにパッケージ化する可能性があります。

全てのコメント30件

優先事項ではありません。 ドラッグソースキー(https://github.com/gaearon/react-dnd/issues/38#issuecomment-73409935)を導入した後、再度アクセスできます。

将来的にはこれに興味がありますが、dragSourceを持つコンポーネントでコンポーネントツリーのセクションをラップするだけでよいと思います...
Shiftキーを押しながらクリックすると、配列のどのセクションがdragItemなどにコピーされるかが展開されます。

ちょっと。

最初に、null component (#38に必要)と同じkey (#53に必要)を持つ別のコンポーネントを渡すことを学びます。

次に、オプションのgroupKeyを追加します。 keyと同様に、ドラッグソースで指定され、文字列です。 groupKeyで何かをドラッグし始めると、呼び出し元だけでなく、同じgroupKeyでマウントされたすべてのドラッグソースでbeginDrag呼び出し、それらのアイテムをに集めます。配列。 item代わりにこれらのアイテムを渡して、ターゲットメソッドを削除します。 ドラッグが終了したら、アイテム配列を使用してドロップターゲットでacceptDropを呼び出し、次に各ドラッグソースのendDragをアイテムで呼び出します。

面白いのは、 items.lengthからのカウントがわかっているので、カスタムの「コンポジット」サムネイルコンポーネントと上記のスクリーンショットのようなカウンターを使用してDragLayerを描画できることです。

それは私が考えていたものよりも醜い考えではありません

:+1:この機能の場合:-)

私は現在これのユースケースを持っていないので、締めくくります、そしてそれは重要な実装努力です。

@gaearon

私は当時Java / Swing DnDを使用していましたが、おそらくこの問題に取り組み、非常に洗練された、非常に汎用的で柔軟なフレームワークを考案した開発者の軍隊がいました。 古いデスクトップフレームワークを調査することをお勧めします。おそらく、このような優れたDnDフレームワークを作成することですべての困難な課題を解決したからです。

Java / Swingでこれを行う方法(ドラッグイメージのサポートは組み込まれていませんでしたが)は、_ツリービュー自体をドラッグソースにし_、_それに基づいてドラッグを開始するかどうかを決定できるようにすることでした。現在の状態とドラッグ開始位置_。 canDragbeginDragが呼び出されたときにmonitor.getInitialSourceClientOffset()利用できますか? 人々は間違いなくそれが利用可能であることを望むでしょう。 また、修飾キー(ctrl、alt、shift)を使用できるようにし、ドラッグソースで移動するかコピーするかを指定したり、ターゲットをドロップして移動やコピーをサポートするかどうかを指定したりできるようにする必要があります。これらの要因は、Java / Swingで可能であり、他のフレームワークを推測しているためです。 Swingには、交換可能な_ドラッグジェスチャレコグナイザー_の概念もありました。

リスト内のすべてのアイテムを個別のドラッグ可能オブジェクトとして扱うことは、リストコンポーネントを、その中で選択されたものに基づいて構築するドロップペイロード/プレビュー画像の種類を把握する単一のドラッグソースにする場合と比較して、難しいと予測します。

また、開発者は、ユーザーがクリックしてドラッグしたアイテムに基づいて、ドラッグするアイテムの順序を変更したい場合があることも考慮してください。Windowsエクスプローラーはこのように動作すると思います。

アプリケーションでreact-dndを使用して複数のアイテムをドラッグすることを実装した人はいますか? これに対するあなたの現在の解決策は何ですか?

単一のドラッグソースの複数のドロップターゲットを意味しましたか?

+1 @ danii1 :複数のアイテムのドラッグを実装した人はいますか?

私はそれを実装しました、解決策は基本的に最初の投稿で説明されているものです:

  1. 選択したアイテムを追跡します
  2. CustomDragLayerを実装し(https://gaearon.github.io/react-dnd/docs-drag-layer.htmlを参照)、選択したアイテムを自分でレンダリングします
  3. ドロップされたアイテムが選択の一部である場合、ドロップを処理します

私はそれを次のように実装しました:

  1. セット内の選択されたアイテムを追跡します
  2. これをプロパティとしてdndSourceに渡します
  3. beginDragで、小道具からセットを取得し、ドラッグアイテムとして返します。
  4. カスタムドラッグプレビューを作成する
  5. EndDragで、セット内のすべてのアイテムをdndターゲットに移動します

これには少し異なるユースケースがあると思います。ドラッグできないエッジでドラッグ可能なノードを描画したいのですが、接続されているノードが移動すると移動します。 私の現在の実装はCustomDragLayerで、 DraggableNodeが移動していることを検出するとエッジを描画します(これもCustomDragLayer描画されますが、 CustomDragLayerが座標を小道具として注入する代わりに、自分自身を描画できるように、接続されているノードが移動しているかどうかを検出するために実装されたisDragging()して、すべてのエッジをDragSourcesとして実装することによる複数のドラッグ状況。

@ danii1
参考までに実装したものを教えてください

投稿を作成し、react-dnd + reduxを使用して複数のネストされたドラッグアンドドロップに関するリポジトリを追加します。

@nayemmajhar 、それは素晴らしいだろう

@nayemmajharこれを使った例の更新はありますか?

私はずっと前にreduxJSでreactDnDを使用してこのアプリケーションを開発しましたhttps://www.joomshaper.com/page-builderチュートリアルを書いていますが、公開する時間が必要です

@serleこれをどのように行ったかのコード例を共有できますか?

@ ianmclean2011ここでそれをチェックしてください: https

https://react-dnd.github.io/react-dnd/examples-sortable-simple.htmlの並べ替え可能な例に似た例でマルチドラッグを実装しようとしてい

誰かが興味を持っているなら、私は複数のドラッグ/グリッドビューを実装しました: https
cmd / ctrlキーとShiftキーを使用して複数のアイテムを選択し、グリッド上でドラッグして任意の場所に挿入できます。

これはまだデモですが、コードをもう少し抽象化して、後でコンポーネントにパッケージ化する可能性があります。

@melvynhills選択したすべてのカードを各カードコンポーネントに渡す必要がないソリューションを調査しましたか? カードのbeginDrag()が選択されたすべてのカードへの参照を必要とすることを考えると、解決策はないと思います。

@jmcrthrsいいえ、react-

@melvynhills @jmcrthrs私が使用した他のデスクトップdndフレームワークは、個々の行、セル、アイテムなどを独自のドラッグソースやドロップターゲットにするのではなく、リストやテーブルをドラッグソース/ドロップターゲットにすることに依存しています。 複数のアイテムをドラッグするための実装、およびリストまたはテーブル内の特定のドロップ位置を取得するための実装は、その方法ではるかにクリーンになります。 リストがドラッグ開始イベントを受信すると、現在選択されているアイテムを簡単に確認できます。

@ jedwards1211このライブラリで実行できると思いますか? 特に、ドラッグ開始前に選択されていなかったアイテムのドラッグを開始するユースケース。 それがreact-dndが機能するはずの方法かどうかはわかりません。

複数のドロップターゲットがある場合を解決した人はいますか?
1つが(上記の解決策の1つを使用して)複数のアイテムをドラッグしていて、1つのアイテムが1つのタイプのドロップターゲットに、もう1つが別のタイプのドロップターゲットに到達するとします。 dropは、ドラッグを開始したドラッグソースに対してのみトリガーされますが、他のソースに対してはトリガーされません。 移動するアイテムごとに個別にドロップをトリガーする方法のアイデア。
例:
Is development slow, Online Whiteboard for Visual Collaboration 2019-11-27 10-45-33

編集:これについては別の問題を作成しましたhttps://github.com/react-dnd/react-dnd/issues/1650

@melvynhillsおそらくmousedownハンドラーがアイテムの選択をトリガーする場合(これを行う必要があります、私が使用したDnDを備えたすべてのソフトウェアはこのように機能します)、コンテナーコンポーネントがドラッグになるReactDnDで問題なく動作しますドラッグイベントはmousedown後に来るためです。

選択したすべてのカードを各カードコンポーネントに渡す必要がないソリューションを調査しましたか?

これは、コンテナコンポーネントを個々のアイテムではなくドラッグソースにすることをお勧めする理由の例です。 React DnDで複数選択を実装する必要はありませんでしたが、サンドボックスを作成して、より保守しやすいアプローチであると人々に納得させることができるかもしれません。

アプリケーションでreact-beautiful-dndを使用して複数のアイテムをドラッグすることを実装した人はいますか? これに対するあなたの現在の解決策は何ですか?

このページは役に立ちましたか?
0 / 5 - 0 評価