{"action":"created","issue":{"url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/97","labels_url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/97/labels{/name}","comments_url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/97/comments","events_url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/97/events","html_url":"https://github.com/ManuelDeLeon/viewmodel/issues/97","id":102405602,"number":97,"title":"Recursive ViewModel support?","user":{"login":"SparserLogic","id":3516389,"avatar_url":"https://avatars.githubusercontent.com/u/3516389?v=3","gravatar_id":"","url":"https://api.github.com/users/SparserLogic","html_url":"https://github.com/SparserLogic","followers_url":"https://api.github.com/users/SparserLogic/followers","following_url":"https://api.github.com/users/SparserLogic/following{/other_user}","gists_url":"https://api.github.com/users/SparserLogic/gists{/gist_id}","starred_url":"https://api.github.com/users/SparserLogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SparserLogic/subscriptions","organizations_url":"https://api.github.com/users/SparserLogic/orgs","repos_url":"https://api.github.com/users/SparserLogic/repos","events_url":"https://api.github.com/users/SparserLogic/events{/privacy}","received_events_url":"https://api.github.com/users/SparserLogic/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-08-21T15:36:41Z","updated_at":"2015-08-21T16:12:12Z","closed_at":null,"body":"Has this been tested? Are there any BKMs?\r\n\r\nI would really like to start converting to this clean solution but I have a nested tree of comments/replies that I'm concerned will cause problems. Things like event binding break in Meteor when you use recursive templating.\r\n\r\nHas this been tested with a similar pattern? How well does it work?"},"comment":{"url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/comments/133478048","html_url":"https://github.com/ManuelDeLeon/viewmodel/issues/97#issuecomment-133478048","issue_url":"https://api.github.com/repos/ManuelDeLeon/viewmodel/issues/97","id":133478048,"user":{"login":"ManuelDeLeon","id":4257750,"avatar_url":"https://avatars.githubusercontent.com/u/4257750?v=3","gravatar_id":"","url":"https://api.github.com/users/ManuelDeLeon","html_url":"https://github.com/ManuelDeLeon","followers_url":"https://api.github.com/users/ManuelDeLeon/followers","following_url":"https://api.github.com/users/ManuelDeLeon/following{/other_user}","gists_url":"https://api.github.com/users/ManuelDeLeon/gists{/gist_id}","starred_url":"https://api.github.com/users/ManuelDeLeon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ManuelDeLeon/subscriptions","organizations_url":"https://api.github.com/users/ManuelDeLeon/orgs","repos_url":"https://api.github.com/users/ManuelDeLeon/repos","events_url":"https://api.github.com/users/ManuelDeLeon/events{/privacy}","received_events_url":"https://api.github.com/users/ManuelDeLeon/received_events","type":"User","site_admin":false},"created_at":"2015-08-21T16:12:12Z","updated_at":"2015-08-21T16:12:12Z","body":"This is a slightly modified version of the comment system I use for meteorcasts (e.g. https://www.meteorcasts.net/ep/6 )\r\n\r\n# commentsBlock\r\nYou drop this wherever you want comments. It provides the top level textarea to post comments. You can drop it anywhere that has an _id. In my case I put a `{{> commentsBlock }}` on each episode and also on a help section.\r\n\r\n```html\r\n<template name=\"commentsBlock\">\r\n  <div class=\"ui segment\">\r\n    <a name=\"comments\"></a>\r\n    <h1>Comments</h1>\r\n    <form class=\"ui reply form\" data-bind=\"if: hasUser\">\r\n      <div class=\"labeled field\">\r\n        <a class=\"ui top right ribbon label\">Markdown</a>\r\n        <textarea data-bind=\"value: newComment, focused: newCommentFocused\"></textarea>\r\n      </div>\r\n      <div class=\"ui labeled submit icon button\" data-bind=\"class: { blue : newComment }, click: addComment\">\r\n        <i class=\"icon edit\"></i> Add Comment\r\n      </div>\r\n    </form>\r\n    <p data-bind=\"if: !hasUser\">\r\n      Sign in to add a comment...\r\n    </p>\r\n    {{> comments }}\r\n  </div>\r\n</template>\r\n```\r\n\r\n```coffee\r\nTemplate.commentsBlock.viewmodel\r\n  _id: -> @parent()._id()\r\n  newComment: ''\r\n  newCommentFocused: false\r\n  addComment: ->\r\n    return if !@newComment()\r\n    Comments.insert\r\n      episodeId: @_id()\r\n      parentComment: @_id()\r\n      message: @newComment()\r\n    @newComment ''\r\n  hasUser: -> Meteor.user()?\r\n  onCreated: (t) ->\r\n    that = this\r\n    t.autorun -> t.subscribe('comments', that._id())\r\n, 'notSubscribed'\r\n```\r\n\r\n# comments\r\nThis is the list of comments directly below the parent.\r\n\r\n```html\r\n<template name=\"comments\">\r\n  {{#if hasComments }}\r\n  <div class=\"ui comments long\">\r\n    {{#each commentList}}\r\n      {{> comment}}\r\n    {{/each }}\r\n  </div>\r\n  {{/if }}\r\n</template>\r\n```\r\n\r\n```coffee\r\nTemplate.comments.viewmodel\r\n  commentList: -> Comments.find({ parentComment: @parent()._id() }, { sort: { createdAt: -1 } })\r\n  hasComments: -> Comments.findOne({ parentComment: @parent()._id?() })?\r\n, ['hasComments', 'commentList']\r\n```\r\n\r\n# comment\r\nA single comment. Notice how it ends with `{{> comments }}` to display any comments below this one (recursively).\r\n\r\n```html\r\n<template name=\"comment\">\r\n  <div class=\"comment\">\r\n    <a class=\"avatar\">\r\n      <img data-bind=\"src: avatar\">\r\n    </a>\r\n    <div class=\"content\">\r\n      <a class=\"author\" data-bind=\"text: author\"></a>\r\n      <div class=\"metadata\">\r\n        <span class=\"date\" data-bind=\"text: date\"></span>\r\n      </div>\r\n\r\n      <div class=\"text\" >\r\n{{#markdown}}\r\n{{message}}\r\n{{/markdown}}\r\n      </div>\r\n\r\n      <div class=\"actions\" data-bind=\"if: hasUser\">\r\n        <a class=\"reply\" data-bind=\"toggle: showReply\">Reply</a>\r\n      </div>\r\n      <form class=\"ui reply form\" data-bind=\"if: showReply\">\r\n\r\n        <div class=\"labeled field\">\r\n          <a class=\"ui top right ribbon label\" href=\"https://en.wikipedia.org/wiki/Markdown#Example\" target=\"_blank\">Markdown</a>\r\n          <textarea data-bind=\"value: newComment\"></textarea>\r\n        </div>\r\n        <div class=\"ui labeled submit icon button\" data-bind=\"class: { blue : newComment }, click: addComment\">\r\n          <i class=\"icon edit\"></i> Add Reply\r\n        </div>\r\n      </form>\r\n    </div>\r\n    {{> comments }}\r\n  </div>\r\n</template>\r\n```\r\n\r\n```coffee\r\nTemplate.comment.viewmodel ( (data) -> 'comment_' + data._id ) ,((data) -> data),\r\n  date: -> @createdAt()?.toRelativeTime(Client.serverTime.get()) or \"Just Now\";\r\n  newComment: ''\r\n  addComment: ->\r\n    return if !@newComment()\r\n    Comments.insert\r\n      episodeId: @episodeId()\r\n      parentComment: @_id()\r\n      message: @newComment()\r\n    @newComment ''\r\n    @showReply false\r\n  showReply: false\r\n  hasUser: -> Meteor.user()?\r\n, 'message'\r\n```\r\n"}}