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.
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?
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:
Saya menerapkannya dengan:
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?
@ianmclean2011 lihat di sini: https://github.com/react-dnd/react-dnd/issues/590
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:
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?
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.