41 votes

Mapper des données JSON vers des observableArray Knockout avec un type de modèle de vue spécifique

Existe-t-il un moyen de mapper un objet de données JSON à un tableau observable et de faire en sorte que chaque élément du tableau observable soit initialisé dans un type spécifique de modèle de vue ?

J'ai regardé toute la documentation de knockout ainsi que les exemples de knockout et de mapping ici et je n'ai pas trouvé de réponse qui fonctionne pour ce que je cherche.

J'ai donc les données JSON suivantes :

    var data = {
    state : {
        name : 'SD',
        cities : [{
            name : 'Sioux Falls',
            streets : [{
                number : 1
            }, {
                number : 3
            }]
        }, {
            name : 'Rapid City',
            streets : [{
                number : 2
            }, {
                number : 4
            }]
        }]
    }
};

Et j'ai les modèles de vue suivants :

var StateViewModel = function(){
    this.name = ko.observable();
    this.cities = ko.observableArray([new CityViewModel()]);
}

var CityViewModel = function(){
    this.name = ko.observable();
    this.streets = ko.observableArray([new StreetViewModel()]);
}

var StreetViewModel = function(){
    this.number = ko.observable();
}

Est-il possible, avec la structure de données donnée et en utilisant le plugin de mapping de knockout, de faire en sorte que le StateViewModel résultant contienne un observableArray peuplé de 2 CityViewModels, et que chaque CityViewModel contienne un observableArray peuplé de 2 StreetViewModels ?

Actuellement, en utilisant le plugin de cartographie, je suis en mesure d'établir une correspondance avec un modèle StateViewModel, mais les collections 'cities' et 'streets' sont peuplées d'objets génériques au lieu d'instances de mes modèles City et Street View.

Ils finissent par avoir les propriétés et les valeurs observables correctes, mais ce ne sont pas des instances de mes modèles de vue, ce qui est ce que je cherche.

69voto

Artem Points 2476

Vérifier ceci http://jsfiddle.net/pTEbA/268/

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

function StateViewModel(data){
    this.name = ko.observable();
    ko.mapping.fromJS(data, mapping, this);
}

function CityViewModel(data) {
    this.name = ko.observable();
    ko.mapping.fromJS(data, mapping, this);
}

function StreetViewModel(data) {
    this.name = ko.observable();
    ko.mapping.fromJS(data, mapping, this);
}

var mapping = {
    'cities': {
        create: function(options) {
            return new CityViewModel(options.data);
        }
    },
    'streets': {
        create: function(options) {
            return new StreetViewModel(options.data);
        }
    }
}

var data = { state: {name:'SD', cities:[{name:'Sioux Falls',streets:[{number:1},{number:3}]},
                                        {name:'Rapid City',streets:[{number:2},{number:4}]}]}};

var vm = new StateViewModel(data.state)
console.log(vm);
console.log(vm.getName());
console.log(vm.cities());
console.log(vm.cities()[0].getName());
console.log(vm.cities()[0].streets());
console.log(vm.cities()[0].streets()[0].getName());
​

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