Knockout.js nested model and observable arrays -
i'm new knockout , have problems @ beginning. consider following model:
// @param {string} content content of post // @param {number} reply_to id indicating post post replying // @param {array} replies array of discussionposts indicating replies post var discussionpost(content, reply_to, replies) { var self = this; self.content = content; self.reply_to = reply_to; self.replies = ko.observablearray( ko.utils.arraymap(replies, function(reply) { return new discussionpost(reply.content, reply.reply_to, reply.replies); }) } now view model, consider have posts in flat array called allposts , try build structure previous model follows:
var rootposts = allposts.filter(function (o) { return o.reply_to === null; }); var result = (function iterate(posts) { var tree = []; $.each(posts, function(i, post){ var replies = allposts.filter(function(o) { return o.reply_to === post.id; }); if (replies.length > 0) { replies = iterate(replies); } var tmppost = new discussionpost(post.content, post.reply_to, replies); tree.push(tmppost); }); return tree; })(rootposts); theoretically, result variable shall contain graph of posts posts don't have parent @ root. instance following tree shall return array 1 element i.e.the root, replies should c1 , c2 , array replies of c1 shall contain c3. problem root filled expected, , replies c1 , c2, replies of c1 returns array 4 elements of type discussionpost properties (content, reply_to, , replies) undefined. if instead of knockouts' observable array use regular javascript array in model works fine @ 100 level deep.
root / \ / \ c1 c2 / c3
how non-recursive approach?
function discussionpost(post) { var self = this; self.content = ko.observable(post.content); self.reply_to = ko.observable(post.reply_to); self.replies = ko.observablearray([]); } var result = (function (posts) { var index = {}, root = "null"; // root level index[root] = new discussionpost({}); // transform discussionpost objects, index id ko.utils.arrayforeach(posts, function (post) { index[post.id] = new discussionpost(post); }); // build tree ko.utils.arrayforeach(posts, function (post) { if (post.reply_to in index) { index[post.reply_to].replies.push(index[post.id]); } else { // orphaned post } }); return index[root].replies; })(allposts); this should perform nicer larger numbers of posts. it's easier read , debug approach.
Comments
Post a Comment