2012-06-27 7 views
10

Ich habe folgendes Coffee Javascript für KnockoutjsCoffeescript, Knockout & beobachtbaren

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 HTML ich diesen 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> 

jedoch verwenden machen zu erzeugen, in der HTML alle Elemente zeigen die Werte von Das letzte NewsItem wurde der Sammlung hinzugefügt.

Irgendwelche Hinweise?

Antwort

20

Okay, kann dies eine der Fallen, die Coffee hat:

class NewsItem 
    content: ko.observable("") 

Hier sind Sie eine neue Klasse mit einer Eigenschaft „Inhalt“ zu schaffen, die ein beobachtbares Objekt ist. Dies kompiliert in die folgenden JavaScript:

var NewsItem = (function() { 
    function NewsItem() {} 
    NewsItem.prototype.content = ko.observable(""); 
    return NewsItem; 
})(); 

Wie Sie jetzt sehen können, die Eigenschaft „Inhalt“ ist mit dem Prototyp angebracht. Das bedeutet: Es wird nur eine Observable erstellt, nicht eine pro Instanz. Wann immer Sie also new NewsItem machen, aktualisiert der Konstruktor diese einzelne Observable im Prototyp, daher derselbe Wert für alle Instanzen.

Um dies zu lösen, einfach das Observable im Konstruktor erstellen. Auf diese Weise ist es zum Beispiel angebracht erhalten, nicht den Prototyp:

class NewsItem 
    constructor: (data,dispForm) -> 
     @content = ko.observable data.get_item("content") 

Kompiliert in (relevanten Teil):

this.content = ko.observable(data.get_item("content")); 
+0

Ich denke, das immer ist, wie es getan werden soll. – Tyrsius

+0

@Tyrsius Das hängt davon ab - wenn Sie ein eigenes Klassenmitglied für jede spezifische Instanz haben möchten (ich muss zustimmen, Sie werden das die meiste Zeit wollen), dann ja. Sie müssen nur den Unterschied kennen. – Niko

+3

Ich nehme an, dass Sie eine statische Eigenschaft wünschen, aber dies sollte die Ausnahme sein, nicht die Regel. – Tyrsius

Verwandte Themen