I have the following CoffeeScript to generate Javascript for Knockoutjs
class NewsItem
content: ko.observable("")
title: ko.observable("")
constructor: (data,dispForm) ->
@content data.get_item("content")
@title data.get_item("title")
@id = data.get_id()
class NewsItemViewModel
collection: ko.observableArray()
loadAll: =>
listEnumerator = items.getEnumerator()
while listEnumerator.moveNext()
currentItem = listEnumerator.get_current()
@collection.push new NewsItem currentItem, @list.get_defaultDisplayFormUrl()
return
$ ->
viewModel = new NewsItemViewModel
ko.applyBindings viewModel
return
To render HTML I use this code
<ul id="results" data-bind="template: {name: 'item_template', foreach: collection}">
</ul>
<script id="item_template" type="text/x-jquery-tmpl">
<li>
<h3><a href="/" data-bind="text: title"></a></h3>
<p>
<textarea data-bind="value: content"></textarea>
<input type="button" value="save" data-bind="enable: content().length > 0">
</p>
</li>
</script>
However, in the HTML all items show the values of the last NewsItem added to the collection.
Any hints?
Okay, this may be one of the pitfalls that CoffeeScript has:
class NewsItem
content: ko.observable("")
Here, you're creating a new class with a property "content" that is an observable object. This compiles into the following JavaScript:
var NewsItem = (function() {
function NewsItem() {}
NewsItem.prototype.content = ko.observable("");
return NewsItem;
})();
As you can see now, the property "content" is attached to the prototype. That means: there is only one observable created, not one per instance. So whenever you do new NewsItem
, the constructor updates this single observable in the prototype, hence the same value for all instances.
To solve this, simply create the observable in the constructor. That way, it get's attached to the instance, not the prototype:
class NewsItem
constructor: (data,dispForm) ->
@content = ko.observable data.get_item("content")
Compiles into (relevant part):
this.content = ko.observable(data.get_item("content"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With