Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

jqGrid - ID exclusivo para nova linha


Abaixo estão alguns conselhos para resolver seu problema principal e melhorar o código JavaScript que você postou.

Em primeiro lugar, a geração de novos rowids localmente é necessário para o cenário de edição local. Deve-se gerar os novos rowids no servidor no caso de salvar os dados no backend no banco de dados. A implementação típica consiste em ter PRIMARY KEY definido como int IDENTITY em todos tabela. Isso torna os ids únicos e fixos. A exclusão de alguma linha e a criação de uma nova nunca será interpretada como edição da linha antiga, pois a nova linha obterá sempre um novo id, que nunca foi usado antes (na tabela).

Para aproveitar os ids gerados no lado do servidor um tem duas opções principais:
  1. recarregar a grade após cada operação Adicionar linha.
  2. estender a comunicação com o servidor na edição para que o servidor retorne um novo id, gerado na tabela do banco de dados, de volta ao jqGrid. Pode-se usar aftersavefunc retorno de chamada (somente para Adicionar nova linha) para atualizar o rowid após a criação bem-sucedida da linha no servidor. Muitas implementações padrão de serviços RESTful retornam dados de linha completos id inclusivo em Adicionar ou Editar. Pode-se usar os dados dentro de aftersavefunc callback e use algo como $("#" + rowid).attr("id", newRowid); para atualizar a nova linha. Ele salvou o id em algumas colunas adicionais (como você usa id oculto coluna) então deve-se usar setCell método adicionalmente para atualizar a célula também.

A primeira escolha é a mais simples e eu recomendo que você a implemente antes de tudo. Somente se o recarregamento da grade não satisfizer os usuários, que adicionam muitas linhas uma após a outra, você deve escrever um pouco mais de código e implementar o segundo cenário.

Seu código atual usa inlineNav para operações Add e Edit, implementadas usando edição em linha, e o método navGrid para a operação Excluir, implementada usando a edição de formulário. A edição do formulário, inclusive Delete, usa reloadAfterSubmit: true opção por padrão. Isso significa que a grade será recarregada do servidor (de url: "/RestWithDatabaseConnection/rest/fetchData" ) após a exclusão de cada linha. Você pode resolver seu problema principal substituindo afterSaveFunction ao seguinte:
var afterSaveFunction = function () {
        $(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
    };

A opção current para manter a seleção atual após recarregar e a opção fromServer: true tem sentido apenas no caso de você usar loadonce: true opção adicionalmente. Você pode simplesmente usar reloadGridOptions: {fromServer: true} opção de navGrid para forçar o recarregamento dos dados do servidor clique no botão Atualizar/Recarregar da barra de navegação. Se você não tiver tantos dados que precise exibir na grade (por exemplo, menos de 1000 linhas), esse comportamento seria recomendado.

Alguns conselhos mais comuns para você melhorar seu código:

Você pode usar height: "auto" em vez de height: 250 e para gerenciar a altura máxima da grade especificando rowNum valor. A opção scrollOffset: 0 será desnecessário no caso.

O formato dos dados retornados do servidor parece que você não implementou paginação, classificação e filtragem do lado do servidor . Você deve usar loadonce: true e forceClientSorting: true opções. O loadonce: true informa ao jqGrid para salvar todos os dados retornados do servidor localmente em data internos parâmetro. Você pode acessar a matriz a qualquer momento usando $('#grid').jqGrid("getGridParam", "data") . O valor de rowNum (o valor padrão é 20) será usado para local paginação. O sortname e a sortorder será usado para local Ordenação. E você usará a caixa de diálogo de pesquisa (adicionada por navGrid ) ou a barra de ferramentas do filtro (adicionada por filterToolbar ) para local pesquisa/filtragem. Simplifica o código do servidor, melhora o desempenho da grade do ponto de vista do usuário e simplifica a interface entre o servidor e o cliente. Você pode usar a interface RESTful clássica no servidor sem nenhuma extensão.

Outra observação:eu recomendo que você remova o id oculto desnecessário coluna (name:'id', label:'id', key: true, hidden: true, ... ). As informações sobre o rowid serão salvas em id atributo das linhas (<tr> element) e não é necessário manter informações duplicadas no <td> oculto elemento em cada linha.

Existem muitas outras partes do seu código, que podem ser melhoradas. Por exemplo, a operação DELETE que você usa no lado do servidor parece estranha. Você usa mtype: 'DELETE' , mas você envia o id da linha excluída dentro de body da solicitação ao servidor em vez de anexá-la à URL. Corresponde aos padrões, o HTTP DELETE deve conter sem corpo . Você pode usar a opção jqGrid formDeleting para especificar todas as opções de Excluir e você pode definir url parâmetro como função:
formDeleting: {
    mtype: "DELETE",
    url: function (rowid) {
        return "/RestWithDatabaseConnection/rest/delete/" + rowid;
    },
    ajaxDelOptions: { contentType: "application/json" },
    serializeDelData: function () {
        return "";
    }
}

Você precisa modificar seu código de servidor de /RestWithDatabaseConnection/rest/delete/ para usar o mesmo protocolo de comunicação e obter o id de delete da URL.

Você pode usar navOptions parâmetro de jqGrid gratuito para especificar as opções de navGrid :
navOptions: { edit: false, add: false }

(searchtext: 'Search' e outras opções que você usa parecem ter valores padrão e eu removi lá).

Para estar mais próximo dos padrões REST, pode-se usar a operação HTTP PUT para edição de linhas e HTTP POST para adicionar novas linhas. Você deve implementar diferentes pontos de entrada para ambas as operações no backend. Você usa /RestWithDatabaseConnection/rest/update já e você pode implementar /RestWithDatabaseConnection/rest/create para adicionar novas linhas. Você pode usar o seguinte inlineEditing mudanças por exemplo para implementar o cenário:
inlineNavOptions: { add: true, edit: true },
inlineEditing: {
    url: function (id, editOrAdd) {
        return "/RestWithDatabaseConnection/rest/" +
            (editOrAdd === "edit" ? "update" : "create");
    },
    mtype: function (editOrAdd) {
        return editOrAdd === "edit" ? "PUT" : "POST";
    },
    keys: true,
    serializeSaveData: function (postData) {
        return JSON.stringify(dataToSend);
    },
    aftersavefunc: function () {
        $(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
    },
    addParams: {
        addRowParams: {
            position: "last",
            serializeSaveData: function (postData) {
                var dataToSend = $.extend({}, postData);
                // don't send any id in case of creating new row
                // or to send `0`:
                delete dataToSend.id; // or dataToSend.id = 0; 
                return JSON.stringify(dataToSend);
            }
        }
    }
}