React-dnd: Como posso obter informações sobre como arrastar arquivos no método canDrop?

Criado em 22 nov. 2016  ·  27Comentários  ·  Fonte: react-dnd/react-dnd

Eu quero restringir a extensão de arquivos permitida e preciso saber quais arquivos o usuário está arrastando, mas o console lança um aviso: NativeDragSources.js:61 Browser doesn't allow reading "files" until the drop event. Então, qual é a melhor maneira de verificar a extensão do arquivo ou arrastar a contagem de arquivos antes de soltá-lo no destino de soltar?

pinned

Comentários muito úteis

Seria possível expor alguma informação sobre os arquivos através do objeto event.dataTransfer (ex. types )? Eu percebo que pode não satisfazer todos os casos de uso, mas ajudaria pelo menos alguns.

Todos 27 comentários

Você está procurando não permitir arrastar na Origem OU mostrar não permitido no Destino com base em um tipo?

  1. para não permitir arrastar, você deve retornar false de canDrag em Source.
  2. para não permitir drop, você deve controlar usando types no Target

@theTechie Não, estou procurando uma maneira de ler a extensão do arquivo que estou arrastando no momento.

Todos os métodos de origem e destino recebem monitor como segundo argumento. (incluindo canDrop )

Você pode usar monitor.getItem() para obter os itens atualmente arrastados.

Referência:

canDrop(props, monitor): Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, just omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
você pode usar o monitor

Não funciona para arquivos

Isso é estranho.
Eu acredito que você está arrastando e soltando arquivos do sistema de arquivos em um destino?

Eu fiz uma coisa semelhante e parece estar funcionando para mim. Se você puder compartilhar algum código, provavelmente poderemos ver o que está errado.

Você poderia mostrar como você lê a extensão do arquivo no método canDrop?

como já mencionei acima, monitor.getItem().files dentro canDrop deve fornecer uma matriz de objetos nativos File

Leia meu primeiro comentário, quando você lê arquivos no canDrop, ele gera um erro como mencionei. Você tem um exemplo de trabalho de leitura de arquivos no canDrop ou apenas consulta a documentação? Erro diz que não consigo ler arquivos até o evento drop NativeDragSources.js:61 O navegador não permite a leitura de "arquivos" até o evento drop

É possível que estejamos usando duas versões diferentes e essa restrição tenha sido adicionada posteriormente. Estou usando 2.1.4.

Ok, vou testar a versão mais recente e aviso se funcionou

Também estou recebendo isso ao tentar filtrar arquivos em canDrop por tipo MIME. Assim que eu chamo monitor.getItem().files , ele lança o aviso acima (Chrome 56.0.2924.87, react-dnd 2.2.4, react-dnd-html5-backend 2.2.4).

De acordo com o MDN meu caso, pelo menos, poderia ser realizado usando uma propriedade em event.dataTransfer , mas até onde eu posso ver, react-dnd não expõe esse objeto ou suas informações em qualquer lugar.

@theTechie

É possível que estejamos usando duas versões diferentes e essa restrição tenha sido adicionada posteriormente. Estou usando 2.1.4.

Não, eu uso a mesma versão. Também atualizado para a versão mais recente possível (2.2.4) e obtendo o mesmo erro:

image

O método canDrop se parece com isso:

canDrop: function (props, monitor) {      
        let files = monitor.getItem().files;
        console.log('Files: ', files);
        return true;
    }

Como isso pode funcionar do seu lado? Você tem exemplo de trabalho?

Vou compartilhar um exemplo de trabalho em breve.
Em segunda-feira, 6 de março de 2017 às 16h12, Andrey Karavaychik [email protected]
escreveu:

@theTechie https://github.com/theTechie

É possível que estejamos usando duas versões diferentes e essa restrição tenha
foi adicionado posteriormente. Estou usando 2.1.4.

Não, eu uso a mesma versão. Também atualizado para a versão mais recente possível
(2.2.4) e obtendo o mesmo erro:

[imagem: imagem]
https://cloud.githubusercontent.com/assets/710513/23606619/8acabe7a-0272-11e7-8db1-b1c88870cf92.png

O método canDrop se parece com isso:

canDrop: function (adereços, monitor) {
deixe arquivos = monitor.getItem().files;
console.log('Arquivos: ', arquivos);
retorne verdadeiro;
}

Como isso pode funcionar do seu lado? Você tem exemplo de trabalho?


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/react-dnd/react-dnd/issues/584#issuecomment-284361793 ,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AA_31panjV9Uo11jF63f2Pkx4FBKiV6Aks5ri-MtgaJpZM4K5hkG
.

>

Cumprimentos,
Gagan

@andrewQwer - realmente sinto muito!
eu tinha uma memória errada do que eu havia implementado e não usa monitor.getItem().files em canDrop , tudo o que estou fazendo é restringir o número de arquivos que podem ser descartados mantendo a contagem de arquivos uma vez ele caiu.

desculpe o engano!

PS: estou procurando maneiras de conseguir isso, vou deixar você saber se eu for capaz.

Acho que isso nunca será possível. Parece que a leitura de informações sobre itens arrastados é restrita intencionalmente por motivos de segurança.

http://stackoverflow.com/questions/25016442/how-to-distinguish-if-a-file-or-folder-is-being-dragged-prior-to-it-being-droppe

Seria possível expor alguma informação sobre os arquivos através do objeto event.dataTransfer (ex. types )? Eu percebo que pode não satisfazer todos os casos de uso, mas ajudaria pelo menos alguns.

Isso pode ser algo a ser adicionado ao backend HTML5, mas parece possível determinar se um arquivo se encaixa em um conjunto aceito de tipos mime antes que o arquivo/pasta seja descartado. Especificamente, react-dropzone faz isso quando você passa o item sobre a dropzone, como pode ser visto neste exemplo .

Alguma solução para este problema ainda?

Este problema foi marcado automaticamente como obsoleto porque não teve atividade recente. Será fechado se não ocorrer mais nenhuma atividade. Obrigado por suas contribuições.

Não obsoleto

Também estou procurando uma maneira de permitir a queda de arquivos específicos, por exemplo: imagens, vídeo, como react-dropzone. Alguém tem uma solução?

Este problema foi marcado automaticamente como obsoleto porque não teve atividade recente. Será fechado se não ocorrer mais nenhuma atividade. Obrigado por suas contribuições.

Eu também tenho o problema. Parece ser bastante codificado no "NativeDragSource.ts".

Ele cria um DragSource, porém, para acessar os valores ele apenas adiciona um console-warning mencionando que o navegador não permitiria.

No entanto, o navegador NÃO permite, está apenas no modo protegido e não permite alterá-lo ou acessar os DADOS (dos arquivos, mas os itens podem com as propriedades dos arquivos deve ser enumerados. (como DropZone faz) .

Vou tentar algo e voltar para você

@LeopoldLerch @darthtrevino Ainda não consigo acessar a lista files antes de cair. Eu quero verificar o tipo mime do arquivo ao passar o mouse e alterar a cor da borda dependendo se é um formato válido do arquivo. Estou usando o método $# canDrop useDrop . E ele retorna uma matriz de arquivos apenas quando eu deixo cair. Quando passo o mouse sobre a zona de soltar, tenho uma matriz vazia

A questão é que os eventos que o navegador entrega são como são, não podemos alterá-los. O navegador dá acesso aos dados apenas no dragstart. Depois disso, todos os eventos subsequentes estão em modo protegido, o que significa que você não pode acessar os dados.

se você usar o método onHover de useDrop, você obterá metadados vazios, pois o navegador não permite que você acesse em "dragenter". Mesmo se você armazenar o objeto no dragstart (ou na função collect), o navegador em segundo plano limpará as propriedades, pois você tem uma referência ao objeto, não uma cópia dele.

A única maneira de contornar isso é usar a função "coletar". Aqui você pode acessar os "itens" ou "arquivos" do item (dependendo do navegador que você usa, o IE11 nunca permitirá que você os acesse antes do ondrop).

no entanto, você tem que fazer tudo sozinho: validando e lembrando, por exemplo. um usoRef. Por exemplo

collect: monitor => {
            const item: DataTransfer = monitor.getItem();
            const isOver = monitor.isOver();
            let _canDrop: VerificationResult = null;
            if (item) {
                if (item.items) {
                    if (item.items.length > 0) {
                        draggedFilesValid.current = allFilesAccepted(
                            fromList<DataTransferItem>(item.items),
                            accept,
                            multiple,
                            maxSize,
                            minSize
                        )
                            ? VerificationResult.Valid
                            : VerificationResult.Invalid;
                    }
                }
            } else {
                draggedFilesValid.current = null;
            }

            if (isOver && item && item.files) {
                _canDrop = VerificationResult.Unknown;
                if (draggedFilesValid.current != null) {
                    _canDrop = disabled
                        ? VerificationResult.Invalid
                        : draggedFilesValid.current;
                }
            }

            return {
                isDragActive: item != null,
                canDrop: _canDrop
            };
        }

@LeopoldLerch
Obrigado pela explicação! vou tentar esse tipo de solução

Esta página foi útil?
0 / 5 - 0 avaliações