2012-03-21 9 views
6

Mam problem z knockout.js i wtyczki mapowania nie tworząc modele tablic podrzędnych w danych źródłowychKnockout.js mapowanie nie wiąże modele podrzędne

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

(To jest mały z repo Mogę na to: Fiddle dostępny tutaj: http://jsfiddle.net/msieker/6Wx3s/)

W skrócie, konstruktor InnerModel nigdy nie jest wywoływany. Próbowałem tego z 'InnerModel' zarówno w tym miejscu, jak i w mapowaniu 'inner'. Z większości relacji z tego, co widziałem, to powinno po prostu działać, ale oczywiście brakuje mi czegoś.

Ktoś ma z tym doświadczenie, które może wskazać mi właściwy kierunek?

EDIT: podstawie @John Earles odpowiedź, stałam się tym nieco bliżej, czego potrzebuję:

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);? 

Jednak parent że zostanie przeniesiony do InnerModel jest null, które coraz to jest cały powód, dla którego używam wtyczki mapowania. Dokumenty prowadzą mnie do przekonania, że ​​to powinno być dostawaniem dostawania się na parametrze options do funkcji create, ale zamiast tego otrzymuję observable, którego wartość to null. Jakieś dodatkowe wskazówki w tym kierunku?

+0

Niestety rodzic nie zrobi tego, co chcesz. W tym przypadku rodzic tworzy tablicę, której częścią jest nowy element, a nie obiekt zawierający tę tablicę. Musisz sam utworzyć skojarzenie rodziców. W ten sposób: http://jsfiddle.net/jearles/6Wx3s/5/ –

+0

możesz spróbować tego http://stackoverflow.com/questions/9951521/map-json-data-to-knockout-observablearray-with-specific- view-model-type Rozwiązało to moje problemy z odwzorowaniem typu child-parent – Naveen

Odpowiedz

2

Nie przekazujesz swoich opcji mapowania (które definiują sposób mapowania wewnątrz) do wywołania odwzorowania OuterModel.

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

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

EDIT: Aktualizacja skrzypce pokazać ręczne mocowanie nadrzędny:

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

1

miałem bardzo podobny scenariusz, natomiast tył, sprawdź Q & A tutaj: Map JSON data to Knockout observableArray with specific view model type

W moim przykładzie mam StateViewModel, który zawiera observableArray wypełnione 2 CityViewModels, a każdy CityViewModel zawiera observableArray wypełnione 2 StreetViewModels.

Potem chciałem zbudować strukturę tego widoku z moich hierarchicznych danych json za pomocą wtyczki mapowania knockout.

Ten skrzypce odwzorowuje się odpowiedź: http://jsfiddle.net/KodeKreachor/pTEbA/2/