Kristoffer Abell Kristoffer Abell - 5 months ago 14
HTML Question

forEach with object properties in KnockoutJS

I have found a few answer regarding this but has not been able to put things together. First day of using Knockout so please let me know if I am thinking about it completely wrong!

I want to represent a list of comments that I have. The comments contain multiple attributes such as {text: ..., score: ..., ...}

I understand that I have a view model

var MatchupViewModel = function(comments) {
this.comments = ko.observableArray(comments);

ko.applyBindings(new MatchupViewModel(comments), document.getElementById("leftchat"));

And I understand that the forEach looks somewhat like this:

  • in jade (which I am using:"forEach: comments")
p.textcontent(data-bind="text: text, visible: text")
img.imagecontent(data-bind="visible: isImage, attr={src: url}")
p.likeButtonMessage(bind-data="click=voteComment(id, true)") &#x25B2
p.dislikeButtonMessage(bind-data="click=voteComment(id, false)") &#x25BC
p.messageScore(data-bind="text: score")

translated to html:

<div id="leftchat" data-bind="forEach: comments" class="chat">
<div class="fullMessage">
<div class="content">
<p data-bind="text: text, visible: text" class="textcontent"></p><img data-bind="visible: isImage, attr={src: url}" class="imagecontent"/>
<div class="scorecontainer">
<div class="buttonContainer">
<p bind-data="click=voteComment(id, true)" class="likeButtonMessage">&#x25B2</p>
<p bind-data="click=voteComment(id, false)" class="dislikeButtonMessage">&#x25BC</p>
<p data-bind="text: score" class="messageScore"></p>

It complains that text is not a function, which is the attribute I had hoped it would have been able to find. How do I work around this?


If you fix the typo's you code should work. forEach should be foreach, and bind-data should be data-bind (unless you made it a custom binding). Have a look at the example below. When text is a falsy value (null, empty string), the node will be hidden, else its value will be visible. This holds true for observable properties too.

var m = {
  comments: [
    {text: 'a'},
    {text: ko.observable('') },
    {text: null},
    {text: ko.observable('c')}

<script src=""></script>
<div id="leftchat" data-bind="foreach: comments" class="chat">
  <div data-bind="text: text, visible: text" class="textcontent"></div>