React-dnd: Dukungan menyeret beberapa elemen

Dibuat pada 25 Okt 2014  ·  30Komentar  ·  Sumber: react-dnd/react-dnd

Ada pola umum yang sulit diterapkan dengan seret dan lepas asli: menyeret banyak elemen. Meskipun mekanisme pemilihan mungkin berbeda dari satu aplikasi ke aplikasi lainnya (cmd+klik, kotak centang, grup yang telah ditentukan sebelumnya), tetapi akan lebih baik untuk setidaknya membuatnya _mungkin_ untuk mendukung skenario ini.

screen shot 2014-10-26 at 1 07 07

Karena beberapa item yang diseret mungkin bukan saudara kandung di DOM dan setDragImage(element, x, y) cukup gila dan belum menjadi lebih baik, kami tidak akan membebani diri kami dengan mencoba merender beberapa elemen dalam pratinjau seret sekaligus.

Bagaimana kami dapat membantu menerapkan skenario ini, jika kami tidak dapat menampilkan pratinjau tarik "beberapa"?

Di satu sisi, skenario ini sudah dimungkinkan: konsumen dapat secara manual melacak elemen yang dipilih, menetapkan dragPreview ke semacam placeholder generik Image dan bereaksi dengan tepat terhadap penghapusan (sejauh bisnis logika yang bersangkutan) beberapa elemen.

Namun saat ini tidak ada cara yang didukung untuk satu elemen untuk mengetahui bahwa itu adalah bagian dari grup yang sedang diseret. Dari sudut pandang react-dnd, jika kita menyeret sesuatu, komponen ini mendapatkan getDragState(type).isDragging = true , tetapi komponen lain tidak. Dari sudut pandang aplikasi Anda, jika Anda mendukung banyak pilihan, Anda ingin semua item yang "dipilih" secara logis menyadari bahwa mereka sedang diseret, meskipun hanya satu yang benar-benar "diseret DOM".

Yang kita butuhkan adalah cara agar komponen memberi tahu react-dnd bahwa, “hei, meskipun onDragStart diterima oleh komponen lain, saya ingin berpura-pura bahwa saya juga sedang diseret, dan mendapatkan getDragState(type) mirror menyeret komponen getDragState(type) , dan endDrag(didDrop) dipanggil juga sehingga saya bisa melakukan pekerjaan saya”.

Bagaimana komponen memilihnya?

design decisions

Komentar yang paling membantu

Jika ada yang tertarik, saya menerapkan beberapa tampilan seret/kisi: https://codesandbox.io/s/9j897k0mwy.
Anda dapat menggunakan cmd/ctrl dan tombol shift untuk memilih beberapa item, lalu menyeretnya di sekitar kisi dan menyisipkannya di mana saja.

Ini masih demo, tapi saya mungkin akan mengabstraksikan kodenya sedikit lagi dan mengemasnya dalam sebuah komponen nanti.

Semua 30 komentar

Bukan prioritas. Kami dapat mengunjungi kembali setelah memperkenalkan kunci sumber seret (https://github.com/gaearon/react-dnd/issues/38#issuecomment-73409935).

Saya akan tertarik dengan ini, meskipun saya pikir Anda mungkin bisa membungkus bagian dari pohon komponen Anda dengan komponen yang memiliki dragSource...
Seperti jika Anda menahan shift dan mengklik, itu memperluas bagian array apa yang disalin ke dragItem atau sesuatu?

Agak.

Pertama kita belajar untuk melewatkan null component (diperlukan untuk #38) dan komponen yang berbeda dengan key (diperlukan untuk #53).

Kemudian kita tambahkan groupKey yang bersifat opsional. Seperti key , itu ditentukan dalam sumber seret dan merupakan string. Ketika Anda mulai menyeret sesuatu dengan groupKey , kami akan memanggil beginDrag tidak hanya pada pemanggil, tetapi pada setiap sumber seret yang dipasang dengan groupKey , dan mengumpulkan item mereka ke sebuah array. Kami akan meneruskan item ini alih-alih item untuk menghapus metode target. Saat drag selesai, kita akan memanggil acceptDrop pada target drop dengan array item, dan kemudian memanggil endDrag masing-masing sumber drag dengan item mereka.

Asyiknya lagi, kita bisa menggambar DragLayer dengan komponen thumbnail “composite” custom dan counter seperti yang saya screenshot di atas karena kita tahu hitungannya dari items.length .

Itu ide yang jauh lebih buruk daripada yang ada dalam pikiran saya

:+1: untuk fitur ini :-)

Penutupan, karena saat ini saya tidak memiliki kasus penggunaan untuk ini, dan ini merupakan upaya implementasi yang signifikan.

@gaearon

Saya menggunakan Java/Swing DnD pada hari itu, dan mereka mungkin memiliki pasukan pengembang yang bergulat dengan masalah ini dan menghasilkan kerangka kerja yang cukup halus, sangat umum, dan fleksibel. Saya akan merekomendasikan untuk meneliti kerangka kerja desktop lama karena mereka mungkin menyelesaikan semua tantangan sulit dengan membuat kerangka kerja DnD yang bagus seperti ini.

Cara untuk melakukan ini di Java/Swing (walaupun tidak memiliki dukungan bawaan untuk menyeret gambar) adalah dengan _menjadikan tampilan pohon itu sendiri sebagai sumber seret_, dan membuatnya _dapat memutuskan apakah seret harus dimulai atau tidak berdasarkan keadaan saat ini dan posisi awal seret_. Apakah monitor.getInitialSourceClientOffset() tersedia saat canDrag dan beginDrag dipanggil? Orang pasti ingin itu tersedia. Mereka mungkin juga ingin kunci pengubah (ctrl, alt, shift) tersedia dan dapat membuat sumber seret menentukan apakah akan memindahkan atau menyalin, dan menjatuhkan target untuk menentukan apakah mereka mendukung pemindahan dan/atau penyalinan, berdasarkan salah satu dari faktor-faktor ini, karena itu mungkin di Java/Swing dan saya kira kerangka kerja lain. Swing juga memiliki konsep _drag gesture recognitions_ yang dapat ditukar.

Saya memperkirakan bahwa memperlakukan semua item dalam daftar sebagai draggable individual hanya akan sulit dibandingkan dengan memiliki komponen daftar menjadi sumber drag tunggal yang mengetahui jenis drop payload/gambar pratinjau untuk dibangun berdasarkan apa yang dipilih di dalamnya.

Pertimbangkan juga bahwa pengembang mungkin ingin _mengubah urutan item yang diseret berdasarkan item yang diklik dan diseret pengguna._ Saya yakin Windows Explorer berperilaku seperti ini.

Adakah yang menerapkan menyeret banyak item dengan react-dnd dalam aplikasi mereka? Apa solusi Anda saat ini untuk ini?

Apakah maksud Anda beberapa target drop untuk sumber drag tunggal?

+1 @danii1 : Apakah ada yang menerapkan menyeret banyak item?

Saya menerapkannya, solusinya pada dasarnya adalah apa yang dijelaskan di posting pertama:

  1. Melacak item yang Anda pilih
  2. Terapkan CustomDragLayer (lihat https://gaearon.github.io/react-dnd/docs-drag-layer.html) dan render sendiri item yang Anda pilih
  3. Menangani drop jika item yang dijatuhkan adalah bagian dari seleksi

Saya menerapkannya dengan:

  1. Melacak item yang dipilih dalam Set
  2. Berikan ini sebagai properti ke Sumber dnd
  3. Di beginDrag, ambil Set dari props dan kembalikan sebagai item drag
  4. Buat pratinjau seret khusus
  5. Pada EndDrag pindahkan semua item di Set ke Target dnd

Saya memiliki kasus penggunaan yang sedikit berbeda untuk ini, saya pikir, saya ingin menggambar simpul yang dapat diseret dengan tepi yang tidak dapat diseret tetapi bergerak ketika simpul yang dilampirkan untuk dipindahkan. Implementasi saya saat ini adalah CustomDragLayer yang menarik tepi ketika mendeteksi DraggableNode bergerak (juga digambar pada CustomDragLayer tetapi saya pikir mungkin lebih baik untuk memodelkannya sebagai beberapa situasi seret dengan menerapkan semua tepi sebagai DragSources dengan isDragging() diimplementasikan untuk mendeteksi jika simpul yang mereka lekatkan bergerak sehingga mereka dapat menggambar sendiri alih-alih CustomDragLayer menyuntikkan koordinat sebagai alat peraga .

@danii1
Bisakah Anda membagikan yang telah Anda terapkan untuk referensi

Saya akan menulis posting dan menambahkan repo tentang banyak dan seret dan lepas bersarang dengan react-dnd + redux.

@nayemmajhar , itu akan sangat bagus

@nayemmajhar ada pembaruan pada contoh dengan ini?

Saya telah mengembangkan aplikasi ini menggunakan react DnD dengan reduxJS sejak lama https://www.joomshaper.com/page-builder Saya menulis tutorial tetapi perlu waktu untuk mempublikasikan

@serle Apakah Anda dapat membagikan contoh kode tentang bagaimana Anda melakukan ini?

Saya mencoba menerapkan multi-seret dalam contoh yang mirip dengan contoh yang dapat diurutkan di sini: https://react-dnd.github.io/react-dnd/examples-sortable-simple.html. Saya ingin dapat memilih objek apa pun, lalu memindahkannya sebagai satu unit ke atas dan ke bawah daftar. Saya mengalami kesulitan untuk memikirkan cara menggunakan contoh/info yang dibagikan di atas untuk melakukan ini. Adakah pemikiran/ide/umpan balik tentang bagaimana ini bisa bekerja?

Jika ada yang tertarik, saya menerapkan beberapa tampilan seret/kisi: https://codesandbox.io/s/9j897k0mwy.
Anda dapat menggunakan cmd/ctrl dan tombol shift untuk memilih beberapa item, lalu menyeretnya di sekitar kisi dan menyisipkannya di mana saja.

Ini masih demo, tapi saya mungkin akan mengabstraksikan kodenya sedikit lagi dan mengemasnya dalam sebuah komponen nanti.

@melvynhills Sudahkah Anda menyelidiki solusi yang tidak mengharuskan meneruskan semua kartu yang dipilih ke setiap komponen Kartu? Saya tidak berpikir ada solusi mengingat beginDrag() Kartu memerlukan referensi ke semua Kartu yang dipilih.

@jmcrthrs Tidak, sepertinya tidak mungkin bagi saya dengan react-dnd API. Saya tidak berpikir ada cara untuk mengetahui sebelum menyeret item spesifik mana yang akan diseret. Itu juga satu-satunya cara untuk mengetahui apakah item yang diseret berada dalam beberapa pilihan yang Anda buat, atau jika berada di luar pilihan itu yang perlu kami ganti.

@melvynhills @jmcrthrs kerangka kerja

@ jedwards1211 apakah menurut Anda itu bisa dilakukan dengan perpustakaan ini? Terutama kasus penggunaan mulai menyeret item yang tidak dipilih sebelum mulai menyeret. Saya tidak yakin itu cara react-dnd seharusnya bekerja.

Apakah ada yang memecahkan kasus di mana ada beberapa target penurunan?
Katakanlah seseorang menyeret beberapa item (menggunakan salah satu solusi di atas) dan satu item berakhir pada satu jenis target penurunan dan yang lainnya pada yang berbeda. drop akan dipicu hanya untuk sumber drag yang memulai drag, tetapi tidak untuk yang lainnya. Ada ide bagaimana memicu penurunan satu per satu untuk setiap item yang dipindahkan.
Contoh:
Is development slow, Online Whiteboard for Visual Collaboration 2019-11-27 10-45-33

EDIT: Membuat masalah terpisah untuk yang ini https://github.com/react-dnd/react-dnd/issues/1650

@melvynhills mungkin jika mousedown memicu pemilihan item (yang harus Anda lakukan, semua perangkat lunak dengan DnD yang saya gunakan berfungsi dengan cara ini), itu akan berfungsi dengan baik dengan React DnD untuk komponen wadah menjadi hambatan source, karena acara drag akan muncul setelah mousedown .

Sudahkah Anda menyelidiki solusi yang tidak mengharuskan semua kartu yang dipilih diteruskan ke setiap komponen Kartu?

Ini adalah contoh mengapa saya akan merekomendasikan menjadikan komponen wadah sebagai sumber seret alih-alih masing-masing item. Saya tidak perlu mengimplementasikan multiselect dengan React DnD tetapi mungkin kadang-kadang saya dapat membuat kotak pasir untuk meyakinkan orang bahwa ini adalah pendekatan yang lebih dapat dipelihara

Adakah yang menerapkan menyeret banyak item dengan react-beautiful-dnd dalam aplikasi mereka? Apa solusi Anda saat ini untuk ini?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat