Qual é a melhor maneira de gerenciar a ordem de classificação dos itens da lista com a interface do usuário Drag & Drop?

10

Eu tenho uma lista de Alunos que devo exibir para o usuário em uma página da Web em formato tabular.
Os itens são armazenados no banco de dados junto com as informações de SortOrder.

Na página da web, o usuário pode reorganizar a ordem da lista arrastando e soltando os itens na ordem de classificação desejada, semelhante a esta postagem .

Abaixo está uma captura de tela da minha página de teste.
insira a descrição da imagem aqui

No exemplo acima, cada linha tem informações de ordem de classificação anexadas a ela. Quando eu largo John Doe (ID do aluno 10) acima da linha ID do aluno 1, a ordem da lista agora deve ser: 2, 10, 1, 8, 11.

Qual é a maneira otimista (com menos recursos) de armazenar e atualizar as informações da ordem de classificação?

Minha única idéia, por enquanto, é que, para cada alteração na ordem de classificação da lista, o valor SortOrder de cada objeto deva ser atualizado, o que, na minha opinião, consome bastante recursos.

Apenas para sua informação: eu posso ter no máximo 25 linhas na minha mesa.

Alexander
fonte
11
Você precisa ter essa ordem de classificação persistente no lado do servidor ou apenas no lado do cliente é suficiente?
deterb
11
Eu devo armazenar o pedido no lado do servidor. Não importa se o pedido está armazenado em cada arrastar-soltar ou clicando em um botão de uma vez por todas.
Alexander

Respostas:

10

Penso em algo que pode reduzir suas consultas. Aqui no meu exemplo, adicionei um novo columnpara classificação chamado pos. Portanto, inicialmente sem arrastar sua mesa, será como:

Estado inicial

Agora, vamos considerar que você arrastou o Item 4entre Item 1& Item 2. Agora, novo posvalor para Item 4será (20 + 10) / 2, o que é 15. Portanto, você só precisará atualizar uma única linha no banco de dados. E você terá -

Após arrastar

Aqui está um fluxograma com os casos de borda. ié o novo índice de matriz da sua linha depois de arrastado -

Fluxograma

Este fluxograma não trata de ArrayOutOfBoundverificações. E, para casos extremos, você precisará de mais de uma consulta.

Como você possui apenas 25 linhas, é possível obter um valor muito grande (por exemplo 10,000) para a diferença de posição (usei 10neste exemplo). Quanto maior o valor, menos ele colidirá.

Rifat
fonte
Essa é uma boa abordagem. Observe que você terá que recalcular a totalidade (ou grande parte) da informação do pedido, se não houver espaço para inserir um item. Seria um evento raro o suficiente para suportar.
9000
@ 9000, você pode usar decimal em vez de inteiro para evitar o problema.
Rifat 12/01
se você tiver Item Aa posição 123 e Item Ca posição 124, não há uma maneira fácil de colocar Item B entre elas. Uma solução seria usar números fracionários (por exemplo, flutuadores), mas eles também têm uma precisão limitada. Às vezes, é melhor fazer uma renumeração, normalizar intervalos e manter as coisas simples.
9000
Então, quando você faz i--, está apenas subtraindo por 1. Não há um intervalo diferente pelo qual você poderia subtrair para evitar possíveis colisões?
muttley91
@Rifat mesmo decimais têm uma precisão limitada, então eles também colidirão.
SCI
3

Pessoalmente, eu retornaria uma matriz JSON para os dados do back-end. Então eu usaria JavaScript (JQuery ou knockout) para exibir, classificar e classificar novamente os dados. Dessa forma, a classificação tem carga zero no servidor.

Tom Squires
fonte
0

Você está procurando uma maneira fácil de lidar com isso, mas a perspectiva amigável também é uma obrigação. Eu recomendo solicitações individuais após cada item reordenado. Cada chamada permite que você verifique se aceita ou falhou.

  • As respostas com falha redefinem a exibição e exibem uma mensagem para o usuário final.
  • Solicitações aceitas simples permitem edição contínua.

Como alternativa, usar um objeto JSON (@ tom-squires) é uma boa idéia para reduzir a sobrecarga de HTTP e o processamento no servidor, mas requer mais código para lidar com solicitações no servidor e no cliente. Se estiver tudo bem, passar o objeto para o servidor é tecnicamente mais eficiente. Ele também permite um atraso de alguns segundos para permitir vários pedidos antes de uma única solicitação, se você desejar.

Lembre-se de que, para fornecer a um usuário um feedback sobre pedidos com falha, você precisará analisar um objeto JSON de resposta do servidor para descobrir qual item falhou e redefinir a interface do usuário com base nisso.

David Garza
fonte
-1

Algo assim no manipulador de eventos de descarte, em que e é o evento DnD.

        ....
        if (e.Action == DragAction.Drop)
        {
            foreach(var item in Items)
            {
                if (e.NewIndex == e.OldIndex) // Dropped in same place
                    return;
                if(e.OldIndex > e.NewIndex) // Moved Up
                {
                    if (item.SortOrder >= e.NewIndex && item.SortOrder < e.OldIndex)
                    {
                        item.SortOrder ++;
                    }
                }
                else // Moved Down
                {
                    if (item.SortOrder> e.OldIndex && item.SortOrder < e.NewIndex) 
                    {
                        item.SortOrder --;
                    }
                }   
            }
            ((Student)e.ItemData).SortOrder = e.NewIndex;
        }
    ...
Entre
fonte