2012-03-21 112 views
6

我在與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

回答

2

您沒有將映射選項(定義如何映射內部)傳遞到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/

1

我有一個非常類似的情景而回,看看將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/