Привязка списка объектов к списку флажков

У меня есть список объектов, каждый из которых содержит несколько полей, например:

function Person(id,name,age) {
    this.id = id;
    this.name = name;
    this.age = age;
}

var listOfPeople = [
    new Person(1, 'Fred', 25),
    new Person(2, 'Joe', 60),
    new Person(3, 'Sally', 43)
];

var viewModel = {
    this.people = ko.observableArray(listOfPeople);
    this.selectedPeople = ko.observableArray([]);
}

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

<ul data-bind="foreach: people">
    <li>
        <input type="checkbox" data-bind="value: id, checked: ?">
        <span data-bind="name"></span>
    </li>
</ul>

Моя путаница в том, что в элементе checkbox data-bind я хотел бы ссылаться как на выбранный объект (то есть на person, так и на человека id)), а также на список всех избранных людей. Как я могу ссылаться на это в области привязки foreach?

Я предполагаю, что это следствие: как я могу ссылаться на связанный объект? Здесь "this", казалось, привязано к окну, а не к объекту.

Пример привязки checked на сайте knockoutjs" относится к примитивам и использует именованный шаблон. Я смущен тем, как это сделать с объектами и с анонимными шаблонами.

Ответ 1

Вы можете сделать что-то вроде:

<ul data-bind="foreach: people">
    <li>
        <input type="checkbox" 
               data-bind="checkedValue: id, checked: $parent.selectedPeople">
    </li>
</ul>

С помощью такого вида ViewModel:

var viewModel = {
    people: ko.observableArray(listOfPeople),
    selectedPeople: ko.observableArray()
};

Атрибут value определяет, что привязка checked добавляет/удаляет из массива, когда он привязан к массиву. Вы также можете написать зависимую функцию, которая заполняет массив фактическими объектами, если это необходимо.

Живой пример:

function Person(id,name,age) {
    this.id = id;
    this.name = name;
    this.age = age;
}

var listOfPeople = [
    new Person(1, 'Fred', 25),
    new Person(2, 'Joe', 60),
    new Person(3, 'Sally', 43)
];

var viewModel = {
    people: ko.observableArray(listOfPeople),
    selectedPeople: ko.observableArray([1])
};

    
ko.applyBindings(viewModel);
<ul data-bind="foreach: people">
    <li>
        <input type="checkbox" value="" data-bind="checkedValue: id, checked: $parent.selectedPeople"><span data-bind="text: name"></span>
    </li>
</ul>

<hr/>

<div data-bind="text: ko.toJSON($root)"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>