web-dev-qa-db-fra.com

Mapper les données JSON vers Knockout observableArray 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, puis à son tour que chaque élément du tableau observable soit initialisé dans un type de modèle de vue spécifique?

J'ai regardé toute la documentation de knockout ainsi que les exemples de knockout et de mappage ici et je ne trouve aucune réponse qui fonctionne pour ce que je recherche.

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 plug-in de mappage de knockout, que le StateViewModel résultant contienne un observableArray rempli avec 2 CityViewModels, et chaque CityViewModel contenant un observableArray rempli avec 2 StreetViewModels?

En utilisant actuellement le plugin de cartographie, je peux le faire mapper à un StateViewModel, mais les collections `` villes '' et `` rues '' sont remplies d'objets génériques au lieu d'instances de mes modèles City et Street View.

Ils se retrouvent avec les bonnes propriétés et valeurs observables, ce ne sont tout simplement pas des instances de mes modèles de vue, ce que je recherche.

41
KodeKreachor

Vérifiez cela 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());
​
69
Artem