この単純な Knockout マッピングが機能しない理由を理解するのにいくつか問題があります。返された JSON が無効なのか、マッピングが間違っているのか、単にバインディングなのかはわかりません。
データ構造は、 Messageオブジェクトの配列を持つ親Conversationオブジェクトです。
私が foreach: Conversation を使用しているバインディングについては、全体を単一の要素配列でラップすると、これが機能するためです。
私のバインディング
<div data-bind="foreach: conversation">
<div data-bind="foreach: messages">
<div class="well">
<div data-bind="text: sender_name"></div>
<div data-bind="text: subject"></div>
<div data-bind="text: body"></div>
<div data-bind="text: updated_at"></div>
</div>
</div>
</div>
私のViewModel、偽のJSONとマッピング
// Sample JSON to return for initialization; 2 second delay
var conversationData = {
json: $.toJSON(
{"id":8,"subject":"Hello JB! Email two!",
"updated_at":"Sep 27",
"originator":"James Pablo",
"count_messages":"(2)",
"messages":[{"subject":"RE: Hello JB! Email two!",
"body":"Thanks for the message!",
"sender_name":"Joe Flynn","updated_at":"Sep 27"},
{"subject":"Hello JB! Email two!",
"body":"Body text",
"sender_name":"James Pablo",
"updated_at":"Sep 27"}
]
}
),
delay: 1
}
function Conversation(data) {
ko.mapping.fromJS(data, {}, this);
}
function Message(data) {
ko.mapping.fromJS(data, {}, this);
}
var map = {
create: function(options) {
return new Conversation(options.data);
},
messages: function(options) {
return new Message(options.data);
}
}
var ViewModel = function() {
var self = this;
self.conversation = ko.observable();
// Use JSFiddle echo to simulate an AJAX service
(function() {
$.ajax({ url:"/echo/json/", data:conversationData, type:"POST",
success:function(data)
{
// Map the returned JSON to the View Model
ko.mapping.fromJS(data, map, self.conversation);
}
});
})();
console.log(self.conversation());
};
ko.applyBindings(new ViewModel());
この JSFiddleは、単一の要素配列にラップされた JSON データを返すときに機能します。
このJSFiddleの JSON から配列ラッパーを削除すると (単一の会話のみをレンダリングしたいので、これが必要です)、それを機能させることができません。何か案は?