具有嵌套模型的KnockoutJS

时间:2015-08-11 13:52:35

标签: javascript knockout.js

我正在寻找一些关于如何创建代表评论系统中帖子的模型的指南。从本质上讲,它是Facebook的一个愚蠢的版本,其中有不同用户的帖子,每个帖子将有零或更多的评论。总是只有一个层次的亲子关系。

我创建Post对象没有问题,但我需要一些帮助来创建和绑定嵌套在帖子下面的注释。如果我有Post模型和Comment模型,我该如何将两者绑在一起?

我试过谷歌,但我找不到与嵌套模型数据绑定的好例子。

示例JSON可以让您对对象的外观有所了解:

`{
  "PostedBy": 1,
  "CommentedByFirstName": "John",
  "CommentedByLastName": "Smith",
  "CommentedByGravatar": "jsmith@gmail.com",
  "Category": "General",
  "CategoryColor": "0076c0",
  "Message": "This is a parent",
  "PostedDate": "2015-06-18T19:32:51.487",
  "PostId": 1008,
  "Anchor": {
    "AnchorId": 9,
    "DashboardId": "1da42665-1cf3-431c-924e-5ed0575315d7"
  },
  "PostComment": [
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-23T20:28:10.887",
      "CommentId": 19,
      "Message": "test5",
      "PostId": 1008
    },
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-18T20:54:33.533",
      "CommentId": 18,
      "Message": "test4",
      "PostId": 1008
    },
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-18T20:54:30.75",
      "CommentId": 17,
      "Message": "test3",
      "PostId": 1008
    }
  ]
}`

1 个答案:

答案 0 :(得分:1)

  

如果我有Post模型和Comment模型,我该如何将两者绑在一起?

您的PostVM将具有一个CommentVM属性的Comments属性。您可以使用简单的foreach绑定将其绑定。像这样:



var post = {
  "PostedBy": 1,
  "CommentedByFirstName": "John",
  "CommentedByLastName": "Smith",
  "CommentedByGravatar": "jsmith@gmail.com",
  "Category": "General",
  "CategoryColor": "0076c0",
  "Message": "This is a parent",
  "PostedDate": "2015-06-18T19:32:51.487",
  "PostId": 1008,
  "Anchor": {
    "AnchorId": 9,
    "DashboardId": "1da42665-1cf3-431c-924e-5ed0575315d7"
  },
  "PostComment": [
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-23T20:28:10.887",
      "CommentId": 19,
      "Message": "test5",
      "PostId": 1008
    },
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-18T20:54:33.533",
      "CommentId": 18,
      "Message": "test4",
      "PostId": 1008
    },
    {
      "CommentedBy": 1,
      "CommentedByFirstName": "John",
      "CommentedByLastName": "Smith",
      "CommentedByGravatar": "jsmith@gmail.com",
      "CommentedDate": "2015-06-18T20:54:30.75",
      "CommentId": 17,
      "Message": "test3",
      "PostId": 1008
    }
  ]
};

function PostVM(postObj) {
    var self = this;
    self.message = postObj.Message;
    // ... other properties
    self.comments = postObj.PostComment.map(function(c) {
        return new CommentVM(c);
    });
};

function CommentVM(commentObj) {
    var self = this;
    self.message = commentObj.Message;
    // ... other properties
};

var vm = new PostVM(post);
ko.applyBindings(vm);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="text:message">
</div>
<hr/>
<ul data-bind="foreach:comments">
    <li data-bind="text:message"/>
</ul>
&#13;
&#13;
&#13;

为了简单起见,我在这里使用了普通属性,但显然你可以为任何应该可写或可更新的属性使用observables(包括一个可观察的注释集合)。

您还应该查看mapping plugin,它将使用一行基本上将整个post对象转换为具有可观察对象的视图模型。这为您节省了大量的属性手动映射。