2013-04-27 4 views
6

По какой-то причине у меня возникли проблемы с передачей объекта наблюдаемому массиву.добавить объект к наблюдаемому массиву с использованием нокаута

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

мой взгляд:

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

Оповещения показывают, что массив всегда пустой, пожалуйста, объясните, что я делаю неправильно спасибо.

ответ

10

Ваше использование видимого массива, например self.events.push(event);, верно (потому что observable array реализует push), только ваши предупреждения ошибочны.

Правильные звонки будут

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

Потому что вам нужно вызвать наблюдаемый массив в качестве функции как регулярного ko.observable, чтобы получить его базовое значение самого массива.

Однако вы в настоящее время добавляете к целому CalendarViewModel в массив, потому что btnAddNewEvent находится за пределами вашей привязки with, поэтому текущий контекст будет вашей основной моделью.

Один из способов решить эту проблему: просто добавьте self.event в массив, так:

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

Но это может вызвать проблемы в дальнейшем, когда вы хотите добавить еще один элемент, потому что вы будете в конечном итоге, ссылающийся на тот же элемент, поэтому правильное решение скопировать свойства где-то:

так что я бы создать функцию конструктора для класса событий:

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

И толкать новое событие в addEvent

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

теперь она работает, но мне кажется, что, когда я использую сигнал (self.events() [0] .имя()); Я получаю эту ошибку: Uncaught TypeError: Object # не имеет метода 'name', когда я печатаю в alert (self.events() [0] .event.name()), тогда это нормально, но разве это не значит, что я храню всю модель представления в моем массиве, а не только свойство события модели представления. Я хочу, чтобы массив удерживал jsut объекты событий, а не модель представления. –

+0

Да, вы теперь добавляете к календарю viewmodel в массив, потому что 'btnAddNewEvent' находится за пределами привязки' with', поэтому текущий контекст будет вашей основной моделью представления. Один из способов решить эту проблему просто и добавить 'self.event' так' self.addEvent = function() {self.events.push (self.event); alert (self.events(). length) alert (self.events() [0] .name()); ' – nemesv

+0

сладкий, работает как ожидалось –

2

Попробуйте

self.events().length 

и

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

вместо этого.

0

Просто обновляйте немного ответа nemesev. Вы действительно не должны проходить data в качестве аргумента

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

И называют это как

self.events.push(new Event()); 
Смежные вопросы