React-dnd: Gunakan di dalam dan / atau dengan iframe.

Dibuat pada 20 Jul 2015  ·  22Komentar  ·  Sumber: react-dnd/react-dnd

Saat konteks, sumber, dan target berada di dalam iframe DnD gagal di-unshift. Saya telah melacaknya kembali ke backend HTML5.js yang disertakan dengan DnD.
Meskipun saya pikir itu mungkin ada hubungannya dengan rerender di iframe. Berikut adalah contoh codepen http://codepen.io/mattconde/pen/zGLXML?editors=101

enhancement wontfix

Komentar yang paling membantu

Setelah banyak mencoba, saya berhasil menjatuhkan elemen di dalam iframe seperti ini:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import FrameComponent from 'react-frame-component';

class DragDropAwareIFrame extends Component {
  static propTypes = {
    innerRef: PropTypes.func,
  };

  static contextTypes = {
    dragDropManager: PropTypes.object.isRequired,
  }

  constructor(props, context) {
    super(props, context);

    this.manager = this.context.dragDropManager;
  }

  componentDidMount() {
    const iframe = ReactDOM.findDOMNode(this.iframe);
    this.manager.getBackend().addEventListeners(iframe.contentWindow);
  }

  componentWillUnmount() {
    const iframe = ReactDOM.findDOMNode(this.iframe);
    this.manager.getBackend().removeEventListeners(iframe.contentWindow);
  }

  handleRef = (el) => {
    this.iframe = el;
    if (this.props.innerRef) this.props.innerRef(el);
  }

  render() {
    const { innerRef, ...props } = this.props;
    return <FrameComponent {...props} ref={this.handleRef} />;
  }
}

<DragDropContextProvider backend={HTML5Backend}>
    <div>
        <Item />
        <DragDropAwareIFrame>
            <div>
                <Dustbin />
            </div>
        </DragDropAwareIFrame>
    </div>
</DragDropContextProvider>

Apakah ini tampaknya cara yang benar untuk melakukannya?

Semua 22 komentar

Menyeret / melepas bingkai di luar kotak juga tidak berhasil untuk saya. Sepertinya peristiwa seret / lepas hanya perlu diterapkan ke setiap objek jendela bingkai tambahan. Saat ini hanya objek jendela tempat Anda menjalankan aplikasi react yang mendapatkannya:

https://github.com/gaearon/react-dnd/blob/master/src/backends/HTML5.js#L130 -L139

Saya menambal HTML5-backend dalam proyek terbaru saya untuk membuatnya bekerja ( setup dan teardown menerima alternatif win objek jendela):

https://gist.github.com/rasmusfl0e/39db428399bd196ef706

Ini juga membutuhkan contoh backend untuk diekspos entah bagaimana (lebih banyak menambal monyet di DragDropContext.js ...) untuk mengeksekusi setup dan teardown saat diperlukan (dalam menyiapkan bingkai Anda) .

Tapi begitu itu selesai - itu bekerja seperti pesona: D

Oh wow, penemuan yang bagus, sangat masuk akal. Akan mencobanya nanti hari ini, dapatkah perubahan di DragDropContext.js dihindari? Dengan begitu kami bisa membuat backend baru seperti yang disebutkan dokumen.

Saya senang untuk mempertimbangkan API tertentu dan proposal implementasi yang menangani masalah ini.
Sayangnya sulit untuk mencerna dari intinya apa yang sebenarnya diubah dan mengapa.

Untuk saat ini, katakanlah kami tidak mendukung iframe.

@ Gaearon Saya mencoba untuk membangun pembuat halaman drag n drop. Mencoba segala sesuatu yang lain dan mereka mengerikan untuk bekerja dengan fluks. Bisakah memberi saya beberapa petunjuk di mana harus men-tweak agar berfungsi dari cross frame?

@nadimtuhin Saya sendiri sedang mengerjakan pembuat halaman lintas bingkai ketika saya mengangkat masalah ini, dan saya akan mulai lagi untuk mendapatkan solusi beberapa jendela yang berfungsi minggu ini. Apakah Anda mengelola iframe dengan react?

Bagi saya, saya tidak yakin apakah bekerja di dalam iframe akan menjadi solusi terbaik lagi, itu pasti akan menyenangkan. Tetapi memiliki tujuan agar react-dnd bekerja di banyak aplikasi tampaknya menjadi opsi yang lebih baik.

Saya telah melihat sekilas kemarin dan baru saja memasukkan beberapa pegangan di backend html5. dan sumber dari jendela pertama terdeteksi pada target dari jendela kedua. Tapi sejauh itu yang saya punya.

@gaearon Beberapa petunjuk / petunjuk tentang tempat mencarinya akan sangat bagus, ingin membuat / mencoba kontrib sumber terbuka pertama saya yang sebenarnya.

@mattconde no Saya tidak mengelola iframe di dalam aplikasi react saya. Saya berencana memiliki dua aplikasi berbeda pada dua bingkai berbeda. Jendela induk menyimpan logika untuk manipulasi data dan bingkai anak untuk presentasi. Anak itu mendapatkan alat peraga dari penyimpanan fluks induk.

@tokopedia

Sulit bagi saya untuk memberikan petunjuk apa pun di samping "coba masukkan log ke dalam backend HTML5 lalu mulailah menyesuaikannya". Ambil contoh sesederhana mungkin dan lihat apakah Anda bisa membuatnya berhasil. Backend hanya melakukan satu hal: berlangganan event window dan event node, dan menerjemahkannya menjadi aksi. Saya tidak cukup tahu tentang cara kerja iframe. Mungkin Anda perlu mengubah kode untuk berlangganan bukan ke jendela, tetapi ke jendela tingkat atas node tertentu (atau iframe) jika ini masuk akal. Tapi saya jauh dari kedalaman saya di sini jadi saya mungkin berbicara sampah.

@gaearon @mattconde

Saya mengalami masalah yang sama baru-baru ini. Alasan gagal adalah karena HTML5Backend menyetel event listener di jendela, tetapi jika Anda ingin menggunakannya di dalam iframe, Anda sebaiknya menyetelnya ke, katakanlah, window.frames [0].

@gaearon Apa pendapat Anda tentang opsi untuk meneruskan konteks ke fungsi penyiapan / pembongkaran di HTML5Backend.js?

Saya telah mengalami masalah yang sama, dengan membangun editor yang disempurnakan (teks, gambar, ..) yang berfungsi dalam iframe dan saya perlu menyeret & melepas elemen (teks, img) di dalamnya, pada dasarnya seret & lepas elemen untuk mengubah memesan.

Saya telah membuka masalah https://github.com/gaearon/react-dnd/issues/435 dan baru tahu itu karena iframe. Saya akan mencoba "mengubahnya" tetapi jika ada solusi, saya akan senang mengetahuinya! :)

Saya mencoba membuat PR agar berfungsi dengan iframe. Saat ini sedang dalam proses, itu belum berhasil, saya mengalami masalah dalam mencari tahu cara memanggil setup dan teardown , masing-masing di componentDidMount dan componentWillUnmount metode.

https://github.com/gaearon/react-dnd-html5-backend/pull/27

@Vadorequest Sepertinya kita berdua mengincar produk akhir yang serupa. Saya tidak berhasil membuatnya bekerja dengan react-dnd dari jendela induk ke anak. Pekerjaan yang saya selesaikan adalah memiliki aplikasi editor (orang tua) dan memiliki aplikasi pratinjau (anak). Aplikasi pratinjau tidak merender sampai dapat terhubung ke toko redux editor.

Kemudian di toko redux saya, saya memiliki daftar template yang saya ingin pengguna seret dari editor ke halaman konten yang bagus. Jadi daftar templat saya ada di jendela Editor, tetapi saya ingin menyeretnya ke Pratinjau.

Berkat react-dnd mendukung tipe asli, saya dapat mengatur seret teks di jendela Editor untuk menyampaikan informasi yang dibutuhkan untuk setiap templat yang akan dirender. Potongan kode saya ...

    componentDidMount() {
        this.refs.template.addEventListener('dragstart', this.handleDragStart, false);
    },
    componentWillUnmount() {
        this.refs.template.removeEventListener('dragstart', this.handleDragStart, false);
    },
    handleDragStart(e) {
        const { template } = this.props;
        e.dataTransfer.setData('text/plain', JSON.stringify({
            type: template.type,
            name: template.name,
        }));
        return e;
    },

Kemudian saya dapat menangkap bahwa string JSON di ujung yang lain dengan react-dnd , bekerja dengan sangat baik.

Beri tahu saya bagaimana Anda maju, ingin sekali mendengar tentang cara alternatif untuk menyiasatinya.

@mattconde Saya sedang mengerjakan dua cabang terpisah, perbaikan jelek dan perbaikan nyata untuk ini. Perbaikan jelek hanya mengubah baris tersebut di file HTML5Backend.js . Perubahan dapat dilihat di sini: https://github.com/Gutenberg-Technology/react-dnd-html5-backend/commit/8b3d6a44b2cdbfe8d5bac025fc263715968d8b6c

_ (pada dasarnya hanya menambahkan target param ke setup dan teardown , yang menjadikan iframe saya sebagai nilai default dan kembali menggunakan window . Perbaikan sangat jelek sehingga benar-benar akan gagal jika tidak ada iframe yang ditemukan, tetapi itu akan berhasil untuk saat ini.) _

Tetapi ini kemungkinan akan gagal pada beberapa situasi, jika ada lebih dari satu iframe, jadi ini hanya untuk menghindari macet. Solusi yang lebih baik adalah secara manual memanggil setup dan teardown dalam kode saya sendiri dengan hanya mengirimkan parameter target untuk mengikat dan melepaskan pendengar.

Terima kasih telah menjelaskan solusi Anda, saya pasti akan meningkatkan PR saya jika saya menemukan solusi yang lebih baik dalam waktu dekat. :)

Hai teman-teman, saya sendiri baru saja mengalami masalah ini, tidak tahu cara menghubungkan jendela dengan iframe. Misalnya saya ingin memiliki beberapa DragSource di jendela dan saya ingin membuat beberapa DropTarget di iframe, bahkan jika saya mengubah HTML5Backend saya tidak bisa membuatnya berfungsi seperti itu ...

@mattconde Terima kasih telah berbagi ini. Saya sedang membangun produk akhir yang serupa. Hal yang lebih buruk adalah kami menggunakan Angular 2. Saya memindahkan react-dnd ke Angular sebagian, tetapi akhirnya, saya menabrak dinding dengan iframe. Akan mencoba caramu.

@gaearon PR di sini ☝️ memungkinkan untuk bereaksi untuk mendukung iframe. Jika Anda memiliki masalah atau ingin saya mengubah apa pun, beri tahu saya.

@kesne Apakah Anda pengelola baru? Bisakah Anda meninjau PR ini?

Halo,
Apakah perubahan Anda memungkinkan untuk menyeret elemen dari halaman ke Bingkai?
Saya dapat menyeret dan menjatuhkan di dalam Bingkai dan di luar.

Hai @crysislinux , saya ingin

apakah ada cara untuk melepaskan item yang berada di luar iframe di dalam iframe misalnya:

<DragDropContextProvider backend={HTML5Backend}>
    <div>
        <Item />
        <Frame>
            <div>
                <Dustbin />
            </div>
        </Frame>
    </div>
</DragDropContextProvider>

Setelah banyak mencoba, saya berhasil menjatuhkan elemen di dalam iframe seperti ini:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import FrameComponent from 'react-frame-component';

class DragDropAwareIFrame extends Component {
  static propTypes = {
    innerRef: PropTypes.func,
  };

  static contextTypes = {
    dragDropManager: PropTypes.object.isRequired,
  }

  constructor(props, context) {
    super(props, context);

    this.manager = this.context.dragDropManager;
  }

  componentDidMount() {
    const iframe = ReactDOM.findDOMNode(this.iframe);
    this.manager.getBackend().addEventListeners(iframe.contentWindow);
  }

  componentWillUnmount() {
    const iframe = ReactDOM.findDOMNode(this.iframe);
    this.manager.getBackend().removeEventListeners(iframe.contentWindow);
  }

  handleRef = (el) => {
    this.iframe = el;
    if (this.props.innerRef) this.props.innerRef(el);
  }

  render() {
    const { innerRef, ...props } = this.props;
    return <FrameComponent {...props} ref={this.handleRef} />;
  }
}

<DragDropContextProvider backend={HTML5Backend}>
    <div>
        <Item />
        <DragDropAwareIFrame>
            <div>
                <Dustbin />
            </div>
        </DragDropAwareIFrame>
    </div>
</DragDropContextProvider>

Apakah ini tampaknya cara yang benar untuk melakukannya?

@ethanve Baru saja kebetulan menemukan utas ini dari masalah penipuan - Saya membuat apa yang Anda jelaskan. https://cormacrelf.github.io/angular-skyhook/

Saya juga mengalami masalah saat menggunakan dnd dalam iframe (tidak ada interaksi orang tua). Menyeret berfungsi dengan baik, tetapi zona lepas tidak berfungsi lagi. Apa solusi untuk membuat zona lepas berfungsi dalam iframe (cukup pindahkan item seluruhnya di dalam iframe).

Saya ingin menunjukkan bahwa ini berfungsi dengan backend Touch tetapi tidak dengan backend HTML5.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat