2014-09-14 6 views
1

Получение проблемы при привязке ko наблюдаемого массива к таблице. [jsFiddle] [1].нокаут foreach привязка только с отображением первого элемента повторно

http://jsfiddle.net/chetanpawar0989/do6o7wtb/

<tbody data-bind="foreach: $root.TakenCourses"> <tr> <td> <span data-bind="text: courseName"></span></td> <td> <span data-bind="text: courseCredits"></span></td> <td> <button data-bind="click: removeCourse">Remove</button></td> </tr> </tbody>

На jsFiddle это просто показывает первый пункт. Однако, когда я добавляю курс, длина массива увеличивается, и последние курсы добавляются к массиву takeCourses (можно увидеть в окне предупреждения). Это означает, что я собираюсь что-то связать с данными.

Также, когда я запускаю тот же код на своей веб-странице, он неоднократно показывает первый курс, когда я добавляю курс.

Функциональность удаления также не работает.

Я новичок в KO и изучаю основы.

ответ

1

Проблема в том, что в объектах course нет функции removeCourse. Поэтому

<button data-bind="click: removeCourse">Remove</button> 

должен быть

<button data-bind="click: $root.removeCourse">Remove</button> 

Вы можете хоть хотите немного переделать все, может быть, как это:

var course = function(name, credits, selected) { 
    var self = this; 

    this.courseName = name; 
    this.courseCredits = credits; 
    this.selected = ko.observable(!!selected); 

    this.unselectCourse = function() { 
     self.selected(false); 
    }; 
}; 

Вместо сохранения списков выбранных и невыбранных курсов, Я бы посоветовал сделать это свойством каждого курса. В модели представления, вы бы затем использовать динамические списки:

function NCSUCourseModel() 
{ 
    var self = this; 

    //Static list of available courses 
    self.courses = ko.observableArray([ 
     new course("Orientation", 1, true), 
     new course("Operating Sytems", 3), 
     new course("Algorithms", 3), 
     // ... 
    ]); 

    self.selectedCourse = ko.observable(); 

    self.AvailableCourses = ko.computed(function() { 
     return ko.utils.arrayFilter(self.courses(), function(item) { 
      return item.selected() == false; 
     }); 
    }); 

    self.TakenCourses = ko.computed(function() { 
     return ko.utils.arrayFilter(self.courses(), function(item) { 
      return item.selected() == true; 
     }); 
    }); 

    self.AddCourse = function() { 
     this.selectedCourse().selected(true); 
    }; 
} 

http://jsfiddle.net/do6o7wtb/2/

+0

спасибо Niko. Новый подход хорош, но просто хотел узнать, в чем проблема со старым. Я попробовал сделать '' в соответствии с вашим предыдущим комментарием, но все равно он не работал. –

+0

Ваш оригинальный JSFiddle смешивает использование 'this' и' self'. Значение 'this' внутри' removeCourse' не будет ссылаться на экземпляр экземпляра NCSUCourseModel, но нокаут будет перерисовываться на экземпляр курса. –

+0

Вы должны использовать '$ parent', а не' $ root', в привязке foreach, чтобы ссылаться на экземпляр viewmodel, содержащий массив. В чем-то другом, кроме упрощенного вида, будет правильный аргумент '$ root'. –