2013-04-27 15 views
6

Z jakiegoś powodu mam problem z przekazaniem obiektu do tablicy obserwowalnej.Dodaj obiekt do obserwowalnej tablicy przy użyciu nokautu

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()); 
} 

mój widok:

<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> 

Alarmy pokazują, że tablica jest zawsze pusty, proszę wyjaśnić, co robię źle dzięki.

Odpowiedz

10

Twoje użycie tablicy obserwowalnej np. self.events.push(event); jest poprawne (ponieważ observable array implementuje push), tylko twoje alerty są błędne.

Prawidłowe połączenia byłaby

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

Bo trzeba zadzwonić do zaobserwowania tablicę jako funkcję jak regularne ko.observable aby uzyskać jego wartość bazowy samą tablicę.

Do tej macierzy dodaje się teraz cały CalendarViewModel, ponieważ btnAddNewEvent znajduje się poza powiązaniem with, więc bieżący kontekst będzie głównym modelem widoku.

Jednym ze sposobów rozwiązania go: wystarczy dodać self.event do tablicy, więc:

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

Ale może to powodować problemy później, gdy chcemy dodać kolejny element, ponieważ skończy się odwołanie do tego samego elementu, więc dobrym rozwiązaniem jest skopiować właściwości gdzieś:

więc chciałbym utworzyć funkcję konstruktora dla klasy zdarzeń:

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()) 
} 

i wcisnąć nową imprezę w addEvent

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

Teraz to działa, ale wydaje się, że gdy używam alert (self.events() [0] .Nazwa()); Otrzymuję ten błąd: Uncaught TypeError: Object # nie ma metody 'name', Kiedy wpisuję alert (self.events() [0] .event.name()), to jest ok, ale nie znaczy, że przechowuję cały model widoku w mojej tablicy, a nie tylko właściwość zdarzenia modelu widoku. Chcę, aby tablica trzymała obiekty zdarzeń, a nie model widoku. –

+0

Tak, obecnie dodajesz do całego kalendarza viewmodel do tablicy, ponieważ 'btnAddNewEvent' znajduje się poza powiązaniem' with', więc bieżący kontekst będzie twoim głównym modelem widoku. Jednym ze sposobów rozwiązania tego problemu i dodania 'self.event', więc' self.addEvent = function() {self.events.push (self.event); alert (self.events(). length) alert (self.events() [0] .name()); " – nemesv

+0

słodki, działa zgodnie z oczekiwaniami –

2

Spróbuj

self.events().length 

i

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

zamiast.

0

Tylko aktualizacja trochę na odpowiedź nemesev. Naprawdę nie trzeba przechodzić data jako argument

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

i nazwać jak

self.events.push(new Event()); 
Powiązane problemy