4 votes

koGrid vide notre grille au lieu de la mettre à jour avec KnockoutJS avec Asp.Net MVC 3

Nous travaillons sur ASP.Net MVC 3 + knockout-2.1.0 et nous essayons de rendre une koGrid mais nous avons un problème Ajax (nous pensons) qui vide la koGrid au lieu de la mettre à jour.

Dans l'état initial, la source de données pour la grille koGrid est un tableau à deux lignes, c'est le ViewModel (vm) :

var viewModel = function() {
    var self = this;
    self.radioSelectedOptionValue = ko.observable('-1');
    self.AvailableActiveProducts = ko.mapping.fromJS(availableActiveProductsObject);
};
ko.applyBindings(new viewModel());

AvailableActiveProducts est la source de données de la grille. Voici le code html :

<div data-bind="koGrid: { data: AvailableActiveProducts }" />

Et la grille s'affiche correctement au départ :

IMG

Le problème commence ici, lorsque la valeur de l'option radioSelectedOptionValue change (c'est le cas avec un changement de contrôle de bouton radio), la grille devrait être mise à jour, mais elle est vidée.

IMG

Nous nous attendons à ce que le bouton radio soit mis à jour/modifié par un appel à la fonction d'abonnement de knockout :

self.radioSelectedOptionValue.subscribe(function() {
    $.get('/SalesOrderManagement/GetProductsBySelection', { 
        typeCriteria: "g", id: 1, seasonType: "1" }, function(data) {
            self.AvailableActiveProducts(data.AvailableActiveProducts);
        });
    }, this);

Dans le contrôleur, la méthode qui répond à cet appel Ajax est :

public JsonResult GetProductsBySelection(string typeCriteria, long id, string seasonType)
{
    var model = _orchestrator.GetProductsByUserCriteria(typeCriteria, id, seasonType);
    return Json(model, JsonRequestBehavior.AllowGet);
}

En déboguant avec fiddler, l'objet json revient (avec les 3 lignes attendues) mais la grille est vide après l'appel.

IMG

Notre hypothèse est que la façon dont les données sont placées dans le tableau observable fait partie du problème. Comment faire pour que cette mise à jour fonctionne correctement ?

Nous pensons avoir trouvé quelqu'un d'autre qui souffre du même problème, mais il n'y a pas eu de réponse sur la liste KO : https://groups.google.com/forum/?fromgroups#!topic/knockoutjs/BS4ugQfV14g

Voici un jsFiddle qui présente le même comportement : http://jsfiddle.net/wabe/H4ZXM/7/

MISE À JOUR : résolu !

Nous avons remarqué, après le commentaire de Tyrsius, que la grille se rafraîchissait après plusieurs clics.

L'ajout d'un pop et d'un push pour forcer le rafraîchissement (selon @Keith) fait que tout fonctionne, la grille se met à jour de la manière attendue. Donc le javascript change pour :

    self.radioSelectedOptionValue.subscribe(function() {
        $.get('/SalesOrderManagement/GetProductsBySelection', { typeCriteria: "gender", id: 1, seasonType: "inseason" }, function(data) {
            self.AvailableActiveProducts(data);
            self.AvailableActiveProducts.push({});
            self.AvailableActiveProducts.pop();
        });

    }, this);

Le "push and pop" effectue la mise à jour finale et le rafraîchissement de la grille. Voici le violon de Keith : http://jsfiddle.net/keith_nicholas/MYYNw/

3voto

Keith Nicholas Points 20875

Il semble que la mise à jour ne soit pas correcte, si vous cliquez sur les colonnes du haut pour les trier, les données apparaissent....

et si je pousse et retire un élément fictif, le code "semble" fonctionner comme vous l'attendez

http://jsfiddle.net/keith_nicholas/MYYNw/

Note : j'ai supprimé la cartographie, car vous ne cartographiez pas vos données initiales, vous cartographiez soit les deux, soit aucune des deux (selon que vous souhaitez observer les changements sur les éléments de données réels).

1voto

ScottRFrost Points 399

J'ai eu exactement ce problème et je l'ai résolu en déplaçant la liaison viewModel à l'intérieur de l'appel ajax.

Vieux et cassés :

            var API_URL = "/api/vendor/";

            window.viewModel = {
                items: ko.observableArray([]),
                item: ko.observableArray([])
            }

            ko.applyBindings(viewModel);

            function getVendors() {
                $.ajax({
                    type: 'GET',
                    url: API_URL,
                    dataType: 'json',
                    success: function (data) {
                        newData = ko.mapping.fromJS(data);
                        viewModel.items(newData);
                    }
                });
            };

            getVendors();

Nouveau Hotness :

           var API_URL = "/api/vendor/";
           $.ajax({
                type: 'GET',
                url: API_URL,
                dataType: 'json',
                success: function (data) {
                    window.viewModel = {
                        items: ko.mapping.fromJS(data),
                        item: ko.observableArray([])
                    }
                    ko.applyBindings(viewModel);
                }
            });

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