Ответ 1
Неужели я делаю это неправильно?
Да. Вы переписываете свой observableArray
в обратном вызове JSON, тем самым уничтожая его:
$.getJSON(baseUri, function (data) {
self.users = data;
});
В общем случае наблюдаемые нокауты присваиваются следующим образом:
$.getJSON(baseUri, function (data) {
self.users(data.$values);
});
Обратите внимание, что в вашем случае data.$values
, похоже, содержит фактический массив, а не data
.
Это сработает для вашего дела, но не полностью использует нокаут.
Для этого случая был создан плагин сопоставления. Он рекурсивно пересекает сложный объект и превращает все его свойства в наблюдаемые и все содержащиеся массивы в наблюдаемые массивы. Это дает вам мелкомасштабный контроль над состоянием объекта, позволяя отслеживать каждое изменение.
$.getJSON(baseUri, function (data) {
ko.mapping.fromJS(data.$values, {}, self.users);
});
Он также позволяет частичные обновления: предположим, что вы получаете список пользователей с сервера, и ваша модель представления уже имеет половину из них. Плагин сопоставления может добавлять только те, которые отсутствуют в вашей модели представления, и вносить соответствующие изменения в существующие. Прочтите раздел "Расширенное использование" в документах, если вы хотите знать, как это сделать.
Предполагая, что вы получаете массив пользовательских объектов с сервера и используете плагин сопоставления, ваша привязка будет выглядеть так:
<ul id="update-users" data-bind="foreach: users">
<li>
<div><div class="item">User ID</div>
<input type="text" data-bind="value: UserId" />
</div>
<div><div class="item">Name</div>
<input type="text" data-bind="value: Name" />
</div>
<ul class="photos" data-bind="foreach: Photos.$values">
<!-- ... -->
<ul>
</li>
</ul>
В общем случае комментарий @Greg Smith корректен. Попытайтесь потерять $
в объектных ключах, они могут столкнуться со специальными переменными в нокауте в какой-то момент. Например, вы можете безопасно заменить их символами подчеркивания.
В более общем примечании я попытался бы исключить все понятие $id
/$values
в вашем JSON, если бы я был вами, это не похоже на какую-либо цель:
[
{
"Locations": [],
"Photos": [],
"UserId": 1,
"Name": "Test User"
}
]