4 votes

La fonction DataSource Destroy de Kendo UI est appelée plus d'une fois pour plusieurs enregistrements.

J'ai un problème étrange dans Kendo UI - que je ne comprends pas.

Voici mon code.

$(document).ready(function() {
    var kendo_dataSource = new kendo.data.DataSource({
        autoSync: true,
        batch: true,
        transport: {
            read: {
                url: "<?php echo BASE_URL . 'kendo/kendo_grid_read' ?>",
                dataType: "json"
            },
            destroy: {
                url: "<?php echo BASE_URL . 'kendo/kendo_grid_destroy' ?>",
                dataType: "json",
                type: "POST"
            },
            parameterMap: function(data, type) {
                if (type == "destroy") {
                    return {models: data.models}
                }
            }
        },
        serverFiltering: true,
        serverGrouping: true,
        serverPaging: true,
        page: 1,
        pageSize: 5,
        schema: {
            data: "results",
            total: "total",
            model: {
                id: "field1"
            }
        }
    });

    $("#kendo_grid2").kendoGrid({
        dataSource: kendo_dataSource,
        height: 300,
        filterable: true,
        sortable: true,
        pageable: true,
        selectable: "multiple row",
        columns: [
            {
                field: "field1"
            },
            {
                field: "field2"
            },
            {
                field: "field3"
            }
        ]
    });

    $("#test_button").on("click", function() {
        var selectedRows = $("#kendo_grid2").data("kendoGrid").select();
        if (selectedRows.length > 0) {
            for (var i = 0; i < selectedRows.length; i++) {
                var dataItem = $("#kendo_grid2").data("kendoGrid").dataItem(selectedRows[i]);
                console.log(dataItem);
                kendo_dataSource.remove(dataItem);
            }
        }
    });

});

Voici la situation.

Lorsque le $("#test_button").on("click", function() est déclenché, il vérifie les rangées sélectionnées dans la grille - et supprime les rangées.

Si je sélectionne 2 lignes, cela supprime 2 lignes. Et les 2 lignes disparaissent de la Grille.

Mais, je vois quelque chose d'étrange -

Lorsque 2 lignes sont supprimées, il y a 2 requêtes POST - ce qui est bien.

Mais les paramètres de la première requête POST sont les suivants

models[0][field1]   3
models[0][field2]   poioioi
models[0][field3]   oiuoiuuigbhkjh
models[0][field4]   kjh kjhkjhyt

Et les paramètres de la deuxième requête POST sont les suivants

models[0][field1]   3
models[0][field2]   poioioi
models[0][field3]   oiuoiuuigbhkjh
models[0][field4]   kjh kjhkjhyt
models[1][field1]   4
models[1][field2]   kjhk hkiui
models[1][field3]   khkj
models[1][field4]   mkhkhkhkjhghgfgdf

Et je comprends que, je peux accéder aux données dans le serveur comme ceci

foreach ($_POST['models'] as $model) {
            echo $model['field1'];           
}

Je me demandais s'il était possible de n'envoyer qu'une seule requête - éventuellement la deuxième requête POST uniquement, car je peux supprimer les deux lignes en une seule requête.

Ou bien envoyer 2 demandes distinctes mais avec un seul modèle à la fois ?

Est-ce possible ?

Toute aide serait grandement appréciée.

3voto

Atanas Korchev Points 20945

Cela est dû au fait que autoSync réglage. Lorsque vous lui attribuez la valeur true, la source de données appelle la fonction sync après chaque modification. Réglage autoSync a false et en appelant manuellement la sync() ferait en sorte que la source de données ne fasse qu'une seule demande avec tous les éléments de données supprimés.

3voto

Chinh Vo Wili Points 65

Dans mon cas, je supprime manuellement les données _destroyed :

event.sender._destroyed = [] ;

 var gridOptions = {
    dataSource: {
        transport: {
            read: {
                url: crudServiceBaseUrl + "gettransactions",
                type: "GET"
            },
            destroy: {
                url: crudServiceBaseUrl + "delete",
                dataType: "jsonp",
                type: "POST"
            },
            parameterMap: function (models, operation) {
                if (operation == "destroy" && models)
                    return { models: kendo.stringify(models) };
            }
        },
        requestEnd: function (event) {
            event.sender._destroyed = [];
            grid.data('kendoGrid').refresh();
        },
        schema: {
            data: "listTransaction",
            total: "total",
            model: {
                id: "TransactionCustomerID",
                fields: {
                    TransactionCustomerID: { editable: false, nullable: true },
                    TransactionTime: { type: "date", editable: false }
                }
            },
            errors: "Errors"
        },
        change: function (event, abc) {
            //todo change fucntion              
        },
        serverPaging: false,
        serverFiltering: false,
        error: function (e) {
            console.log("Status: " + e.status + "; Error message: " + e.errorThrown);
        }
    },
    batch: true,
    editable: "popup",
    autoSync: true,
    resizable: true,
    columns: columnOptions,
    sortable: { mode: "single", allowUnsort: true },
    filterable: false,
    pageable: {
        pageSize: 20,
        pageSizes: [20, 50, 100],
        refresh: true
    },
    cancel: function () {
        grid.data('kendoGrid').dataSource.read();
        grid.data('kendoGrid').refresh();
    },
    dataBound: function (e) {
        hideGridButtonText(".k-delete");
        handleEmptyData(e);
    },
    excel: {
        fileName: "Transaction List.xlsx",
        filterable: true,
        allPages: false,
        downloadElement: "#exportexcel"
    }
};

Ça marche !

1voto

Majix Points 71

J'avais un problème similaire.

J'utilise une fonction pour l'attribut destroy du dataSource. Mon problème était qu'à chaque suppression successive d'une ligne, la fonction destroy était appelée une fois de plus de manière cumulative. Cela signifie que pour la première suppression, la fonction est appelée une fois, pour la deuxième suppression, elle est appelée deux fois, et ainsi de suite.

Dans mon cas, le problème était dû au fait que je ne notifiais pas le dataSource de la suppression réussie. Ci-dessous, vous trouverez la partie correspondante du code de Kendo UI. documentation . J'ai manqué la partie du succès.

    destroy: function (options) {
      $.ajax({
        url: "http://demos.kendoui.com/service/products/destroy",
        dataType: "jsonp",
        data: {
          models: kendo.stringify(options.data.models)
        },
        success: function(result) {
          // notify the data source that the request succeeded
          options.success(result);
        },
        error: function(result) {
          // notify the data source that the request failed
          options.error(result);
        }
      });

0voto

Lionel Points 15

Ok, donc je pense avoir trouvé l'origine du problème.

J'ai souscrit à l'événement d'erreur de source de données et j'ai vu qu'une erreur s'est produite pendant l'analyse de JSon (parseerror). Donc le dataItem n'est pas supprimé du datasource. (c'est pourquoi la source de données n'est pas bien synchronisée, j'avais raison sur ce point).

L'erreur de syntaxe s'est produite parce que mon webservice de suppression renvoie une chaîne vide.

Maintenant, je dois trouver le moyen de le résoudre...

0voto

Paul Alwin Points 161

Pour moi, il suffisait de mettre autoSync à faux ! Essayez-le.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X