将JSON数据映射到具有特定视图模型类型的Knockout observableArray [英] Map JSON data to Knockout observableArray with specific view model type

查看:105
本文介绍了将JSON数据映射到具有特定视图模型类型的Knockout observableArray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种方法可以将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个CityViewModel填充的observableArray,而每个CityViewModel包含一个由2个StreetViewModels填充的observableArray?

当前使用映射插件可以将其映射到StateViewModel,但是城市"和街道"集合中填充了通用对象,而不是我的城市"和街景"视图模型的实例.

它们最终具有正确的可观察属性和值,它们只是我所追求的不是我的视图模型的实例.

解决方案

选中此 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());
​

Is there a way to map a JSON data object to an observable array and then in turn have each item of the observable array be initialized into a specific type of view model?

I've looked at all of knockout's documentation along with the knockout and mapping examples here and I can't find any answer that works for what I'm after.

So, I have the following JSON data:

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

And I have the following view models:

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

Is it possible, with the given data structure and using knockout's mapping plugin, to have the resulting StateViewModel contain an observableArray populated with 2 CityViewModels, and each CityViewModel containing an observableArray populated with 2 StreetViewModels?

Currently using the mapping plugin I'm able to get it to map to a StateViewModel, but the 'cities' and 'streets' collections are populated with generic objects instead of instances of my City and Street view models.

They end up with the correct observable properties and values on them, they're just not instances of my view models, which is what I'm after.

解决方案

Check this 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());
​

这篇关于将JSON数据映射到具有特定视图模型类型的Knockout observableArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆