Карта данных JSON для нокаута наблюдаемого массива с определенным видом типа модели
Есть ли способ сопоставить объект данных JSON с наблюдаемым массивом, а затем, в свою очередь, будет ли каждый элемент наблюдаемого массива инициализироваться в определенный тип модели представления?
Я просмотрел всю документацию нокаута вместе с примерами нокаута и сопоставления здесь, и я не могу найти ответ, который работает для того, что мне нужно.
Итак, у меня есть следующие данные JSON:
var data = {
state : {
name : 'SD',
cities : [{
name : 'Sioux Falls',
streets : [{
number : 1
}, {
number : 3
}]
}, {
name : 'Rapid City',
streets : [{
number : 2
}, {
number : 4
}]
}]
}
};
И у меня есть следующие модели представлений:
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();
}
Возможно ли, с данной структурой данных и использованием плагина отображения нокаута, чтобы получившийся в результате StateViewModel содержал наблюдаемый массив, состоящий из 2-х CityViewModels, и каждый CityViewModel, содержащий наблюдаемый массив, заполненный 2-мя объектами StreetViewModels?
В настоящее время с использованием плагина сопоставления я могу получить его для сопоставления с StateViewModel, но коллекции "городов" и "улиц" заполняются общими объектами, а не экземплярами моих моделей просмотра City и Street.
В результате они получают правильные наблюдаемые свойства и значения, они просто не являются экземплярами моих моделей взглядов, и это то, что мне нужно.
Ответы
Ответ 1
Отметьте 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());