2012-03-30 16 views
41

Gibt es eine Möglichkeit, ein JSON-Datenobjekt einem beobachtbaren Array zuzuordnen und dann jedes Element des beobachtbaren Arrays wiederum in einem bestimmten Typ eines Ansichtsmodells zu initialisieren?JSON-Daten zu Knockout observableArray mit spezifischer Sicht modellieren

Ich habe die gesamte Knockout-Dokumentation zusammen mit den Knockout- und Mapping-Beispielen hier angeschaut und ich kann keine Antwort finden, die für das, wonach ich suche, funktioniert.

Also, ich habe folgende JSON-Daten:

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

Und ich habe folgende Ansicht Modelle:

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(); 
} 

Ist es möglich, mit der Datenstruktur gegeben und Mapping-Plugins mit Knockout, Das resultierende StateViewModel enthält ein ObservableArray, das mit 2 CityViewModels gefüllt ist, und jedes CityViewModel, das ein ObservableArray mit 2 StreetViewModels enthält.

Momentan benutze ich das Mapping-Plugin, um es einem StateViewModel zuordnen zu können, aber die 'cities' und 'street'-Sammlungen werden mit generischen Objekten statt Instanzen meiner City- und Street-View-Modelle gefüllt.

Sie enden mit den richtigen beobachtbaren Eigenschaften und Werten auf ihnen, sie sind einfach keine Instanzen meiner Ansichtsmodelle, nach denen ich suche.

Antwort

68

prüfen diese 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()); 
​ 
+1

ich eine obwohl Frage nachgehen hatte: wenn 'der Städte zu schaffen, sieht es aus wie das' create' Mapping ein einzelnes Objekt vom Typ 'CityViewModel' tatsächlich zurückkehrt, und übergeben wird ein Stadtobjekt. Was würden Sie tun, wenn Sie eine Sammlungsart wie "CitiesViewModel" mit eigenen Erfassungsmethoden haben möchten? –

+0

Sieht gut aus? Aber was macht das 'this. $ Type = '..Model' in den Konstruktoren? Ich kann nichts über eine '$ type'-Eigenschaft in der Online-Knockout- oder Knockout.mapping-Dokumentation finden. – Bart

+0

$ type ist eigentlich nicht notwendig ... nur um zu demonstrieren, dass der Konstruktor aufgerufen wurde. – Artem

Verwandte Themen