Knockout.js映射没有约束力

问题描述:

我在与knockout.js一个问题,映射插件的源数据Knockout.js映射没有约束力

var data = { 
    outer: [ 
     { 
     'id': 1, 
     name: 'test outer', 
     inner: [{ 
      'id': 1, 
      name: 'test inner'}]}] 
}; 

function OuterModel(data) { 
    var self = this; 
    ko.mapping.fromJS(data, {}, this); 

    self.fullText = ko.computed(function() { 
     return self.id() + ". " + self.name(); 
    }); 
} 

function InnerModel(data, parent) { 
    var self = this; 
    ko.mapping.fromJS(data, {}, this); 

    self.fullText = ko.computed(function() { 
     return self.id() + ". " + self.name() + "(" + parent + ")"; 
    }); 
} 

function PageModel() { 
    var self = this; 
    this.data = null; 
} 

var mapping = { 
    'outer': { 
     key: function(data) { 
      return ko.utils.unwrapObservable(data.id); 
     }, 
     create: function(options) { 
      var thisModel = new OuterModel(options.data); 
      return thisModel; 
     } 
    }, 
    'inner': { 
     key: function(data) { 
      return ko.utils.unwrapObservable(data.id); 
     }, 
     create: function(options) { 
      var thisModel = new InnerModel(options.data); 
      return thisModel; 
     } 
    } 
}; 

var model = new PageModel(); 
model.data = ko.mapping.fromJS(data, mapping); 

不创建子阵列模式(这是一个小回购的儿童模特我可以做到这一点。小提琴可在这里:http://jsfiddle.net/msieker/6Wx3s/

总之,InnerModel构造函数永远不会被调用。我已经在'InnerModel'这个代码片段中以及在'inner'映射中试过了。从我见过的大多数报道来看,这应该是正常的,但显然我错过了一些东西。

任何人都有这方面的经验,可以指出我在正确的方向吗?

编辑: 基于@约翰Earles答案,我已经得到了这个有点接近我所需要的:

var data = { 
    outer: [ 
     { 
     'id': 1, 
     name: 'test outer', 
     inner: [{ 
      'id': 1, 
      name: 'test inner'}]}] 
}; 

var outerMapping = { 
    'outer': { 
     key: function(data) { 
      return ko.utils.unwrapObservable(data.id); 
     }, 
     create: function(options) { 
      var thisModel = new OuterModel(options.data); 
      return thisModel; 
     } 
    } 
}; 

function OuterModel(data) { 
    var self = this; 
    ko.mapping.fromJS(data, innerMapping, this); 

    self.fullText = ko.computed(function() { 
     return self.id() + ". " + self.name(); 
    }); 
} 

var innerMapping = { 
    'inner': { 
     key: function(data) { 
      return ko.utils.unwrapObservable(data.id); 
     }, 
     create: function(options) { 
      console.log(options); 
      var thisModel = new InnerModel(options.data, options.parent()); 
      return thisModel; 
     } 
    } 
}; 

function InnerModel(data, parent) { 
    var self = this; 
    ko.mapping.fromJS(data, {}, this); 

    self.fullText = ko.computed(function() { 
     return self.id() + ". " + self.name() + "(" + parent + ")"; 
    }); 
} 

function PageModel() { 
    var self = this; 
    this.data = null; 
} 

var model = new PageModel(); 
model.data = ko.mapping.fromJS(data, outerMapping); 
ko.applyBindings(model);? 

然而,被传递给InnerModel的parentnull,这让这是我追求地图插件的全部原因。这些文档让我相信这应该会越过options参数传递给create函数,但取而代之的是observable,其值为null。在这个方向上的任何额外的指针?

+0

不幸的是父母不会做你想做的。在这种情况下,父项为您的数组提供了新项目的一部分,而不是包含该数组的对象。您需要自己制作父协会。像这样:http://jsfiddle.net/jearles/6Wx3s/5/ – 2012-03-29 00:24:40

+0

你可以试试这个http://stackoverflow.com/questions/9951521/map-json-data-to-knockout-observablearray-with-specific- view-model-type 这解决了我的问题与子 - 父映射 – Naveen 2012-08-09 02:36:23

您没有将映射选项(定义如何映射内部)传递到OuterModel映射调用中。

function OuterModel(data) { 
    var self = this; 
    ko.mapping.fromJS(data, mapping, this); 

    self.fullText = ko.computed(function() { 
     return self.id() + ". " + self.name(); 
    }); 
} 

编辑:更新小提琴显示母公司的手动附件:

http://jsfiddle.net/jearles/6Wx3s/5/

我有一个非常类似的情景而回,看看将q &一个here:Map JSON data to Knockout observableArray with specific view model type

在我的示例中,我有一个StateViewModel,其中包含一个用2个CityViewModel填充的observableArray,每个CityViewModel包含一个使用2个StreetViewModel填充的observableArray。

然后,我希望这个视图模型结构可以使用knockout的映射插件从我的分层json数据中构建。

这个小提琴映射出答案:http://jsfiddle.net/KodeKreachor/pTEbA/2/