Как изменить значения fromJson
-
13-10-2019 - |
Вопрос
Пожалуйста, рассмотрите следующее представление:
<p>Count <span data-bind="text: unreadCount()"> </span></p>
<div data-bind='template: { name: "conversationTemplate", data: currentList }'> </div>
<script type="text/html" id="conversationTemplate">
<table>
<tbody>
{{each $data}}
<tr id="conversation_${conversation_id}" class="conversation-item ${status}">
<td><input type="checkbox" data-bind="click: function() { alert(this.value) }, checked: read" /></td>
</tr>
{{/each}}
</tbody>
</table>
</script>
И следующий код:
$(function() {
var viewModel = {
currentList : ko.observableArray([])
};
ko.dependentObservable(function () {
$.ajax({
url: '/conversations/inbox.json', dataType: 'json',
success: function(data) {
viewModel.currentList(data.conversationlist);
}
});
}.bind(viewModel));
viewModel.unreadCount = ko.dependentObservable(function() {
var unreadCount = 0;
for (var i = 0; i < viewModel.currentList().length; i++)
if (viewModel.currentList()[i].read == true) {
unreadCount++;
}
return unreadCount;
});
ko.applyBindings(viewModel);
Выше, кажется, работает, хотя я не уверен, что я построил это правильно. Что я хочу научиться делать, это когда вы меняете флажок, как иметь unreadCount
Будьте автоматически обновлены, чтобы отразить изменение. Я думал, что использование KO будет предоставить это автоматически, но, возможно, мне нужно что-то сделать в распределении данных шаблона?
Кроме того, как только я смогу изменить флажок и автоматически обновлять модель View Model & Unroad, как правильный способ отправить это обновление обратно на сервер (Rails)?
Вот пример ответа JSON с сервера:
{
"conversationlist": [{
"project_name": "Proj 1",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 2",
"preview": "xxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 3",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}]
}
Решение
Похоже, вы могли бы выполнить функцию на нажимать (внутри data-bind='click: function() {...}'
) для каждого элемента, который увеличивает или уменьшает нечищенную счетчик в зависимости от значения проверенного флажона. Таким образом, вам никогда не придется проходить через currentList
и обновить непрочитанное количество таким образом.
Вы также можете подписаться на ViewModel read
свойство явно и выполните свой собственный код, когда read
Изменения (см. «Явное подписку на наблюдаемые» в середине Наблюдаемая документация).
Редактировать: Вот Поток, в котором один пользователь описывает, как они настраивают наблюдаемый массив с элементами с наблюдаемыми свойствами. ЗдесьПример того, что автор (Стив Сандерсон) придумал демонстрацию наблюдаемых массивов со наблюдаемыми свойствами.
С обоими методами кажется, что вы можете выполнить вызов Ajax, чтобы отправить обратно на сервер.
Обновлять: Вот пример того, как вы можете реализовать это:
$(function() {
var initialData = {/*Data retrieved by AJAX or on page load*/};
var markRead = function(conversation) {
// Make AJAX POST here to update read status of
// the conversation
};
// Convenience object for conversations.
var Conversation = function(conversation_id, status, read) {
this.conversation_id = conversation_id;
this.status = status;
this.read = ko.observable(read);
};
var initialUnread = 0;
var viewModel = {
// Map the conversation list to a new array containing
// objects with observable properties.
conversationList: ko.observableArray(ko.utils.arrayMap(
initialData.conversationlist, function(data) {
if (!data.read === false) {
initialUnread++;
}
return new Conversation(
data.conversation_id,
data.status,
data.read);
})),
unreadCount: ko.observable(initialUnread),
// Executed when the user toggles a conversation's
// read status.
toggleRead: function(conversation) {
// Update the unread count.
viewModel.unreadCount(
viewModel.unreadCount() +
(conversation.read() ? 1 : -1));
// Update the conversation via AJAX
markRead(conversation);
return true;
}
};
ko.applyBindings(viewModel);
});
Заметки:
- Не использует плагин с отображением. Общая логика должна быть такой же.
- Если вызов Ajax не сбои, вы, вероятно, должны обновить флажок с его статусом перед щелчком.
- Вы можете обновить
unreadCount
Собственность в ViewModel в любом месте, позвонив по телефонуviewModel.unreadCount(<value>)
. - Это основано на нескольких примерах, в частности Вот этот. Анкет Сложные примеры особенно открывают глаза и демонстрируют некоторые классные вещи, которые вы можете сделать с КО.