2013-04-27 13 views
6

Aus irgendeinem Grund habe ich Probleme, ein Objekt zu beobachtbaren Array zu übergeben.Object zu Observable Array mit Knockout hinzufügen

function CalendarViewModel() { 
var self = this; 

self.event = { 
    name : ko.observable(""), 
    adress : ko.observable(""), 
    startTime : ko.observable(""), 
    endTime : ko.observable("") 
} 

self.events = ko.observableArray([ 

]) 

self.addEvent = function (event) { 

    self.events.push(event); 

    alert(self.events.length) 
    alert(self.events[0].name()); 
} 

meiner Sicht:

<fieldset class="add-event-fieldset"> 
      <div data-bind="with: event"> 
       <legend>Add Event</legend> 
       <div style="text-align: center;"> 
        <label class="title-label">What </label> 
       </div> 
       <div> 
        <label>Name: </label> 
        <input type="text" name="whatTxtBox" data-bind="value: name" /> 
       </div> 
       <div> 
        <label>Where: </label> 
        <input type="text" name="whereTxtBox" data-bind="value: adress" /> 
       </div> 
       <div style="text-align: center;"> 
        <label class="title-label">When </label> 
       </div> 
       <div> 
        <label>start: </label> 
        <input type="text" id="startHourTxtBox" data-bind="value: startTime" /> 
       </div> 
       <div> 
        <label>end: </label> 
        <input type="text" id="endHourTxtBox" data-bind="value: endTime" /> 
       </div> 
      </div> 

      <input type="hidden" name="" id="hiddenDay" /> 

      <button id="btnAddNewEvent" data-bind="click: $root.addEvent">+</button> 
     </fieldset> 

Die Warnungen zeigen, dass das Array immer leer ist, bitte erklären, was ich falsch mache Dank.

Antwort

10

Ihre beobachtbare Array-Verwendung z. B. self.events.push(event); ist korrekt (weil observable array implementiert push), nur Ihre Warnungen sind falsch.

Die richtigen Anrufe

alert(self.events().length) 
alert(self.events()[0].name()); 

sein würde, weil Sie die beobachtbare Matrix als eine Funktion wie die regelmäßige ko.observable zu bekommen ihr zugrunde liegenden Wert das Array selbst aufrufen müssen.

Sie fügen jedoch gerade CalendarViewModel zu dem Array hinzu, weil die btnAddNewEvent außerhalb Ihrer with Bindung ist, so dass der aktuelle Kontext Ihr Hauptansichtsmodell sein wird.

Ein Weg, um es zu lösen: nur die self.event zum Array hinzufügen, so:

self.addEvent = function() 
{ 
    self.events.push(self.event); 
    alert(self.events().length) 
    alert(self.events()[0].name()); 
} 

Aber dies kann später zu Problemen führen, wenn Sie ein anderes Element hinzufügen möchten, weil Sie das gleiche Element wird am Ende Referenzierung so die richtige Lösung ist, die Eigenschaften kopiert irgendwo:

so würde ich eine Konstruktorfunktion für Ihre Event-Klasse erstellen:

var Event = function(data) { 
    var self = this; 
    self.name = ko.observable(data.name()), 
    self.adress = ko.observable(data.adress()), 
    self.startTime = ko.observable(data.startTime()), 
    self.endTime = ko.observable(data.endTime()) 
} 

und schieben ein neues Event in der addEvent

self.events.push(new Event(self.event)); 
+0

jetzt ist es funktioniert, aber es scheint, dass, wenn ich alert (self.events() [0] .Name()); Ich erhalte diesen Fehler: Uncaught TypeError: Object # hat keine Methode 'name', Wenn ich einen Alarm eintippe (self.events() [0] .event.name()), dann ist es in Ordnung, aber bedeutet das nicht, dass ich speichere das gesamte Ansichtsmodell in meinem Array und nicht nur die Ereigniseigenschaft des Ansichtsmodells. Ich möchte, dass das Array nur die Ereignisobjekte enthält, nicht das Ansichtsmodell. –

+0

Ja, Sie fügen gerade dem View-Model des ganzen Kalenders zum Array hinzu, weil 'btnAddNewEvent' außerhalb der' with'-Bindung liegt, so dass der aktuelle Kontext Ihr Haupt-View-Modell ist. Ein Weg, um es zu lösen, und fügen Sie das 'self.event' so hinzu' self.addEvent = function() {self.events.push (self.event); alert (self.events(). length) alert (self.events() [0] .name()); ' – nemesv

+0

süß, funktioniert wie erwartet –

2

self.events().length 

Versuchen und

self.events()[0].name() 

statt.

0

Nur ein wenig Aktualisierung auf nemesev Antwort. Sie wirklich müssen nicht data als Argument übergeben

var Event = function() { 
    var self = this; 
    self.name = ko.observable(); 
    self.adress = ko.observable(); 
    self.startTime = ko.observable(); 
    self.endTime = ko.observable(); 
}; 

Und nennen Sie es wie

self.events.push(new Event());