Вопрос

Пожалуйста, рассмотрите следующее представление:

<p>Count <span data-bind="text: unreadCount()">&nbsp;</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>).
  • Это основано на нескольких примерах, в частности Вот этот. Анкет Сложные примеры особенно открывают глаза и демонстрируют некоторые классные вещи, которые вы можете сделать с КО.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top