jquery - 如何修改 JSON 中的值

标签 jquery knockout.js

请考虑以下观点:

<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以反射(reflect)更改。我认为使用 ko 会自动提供此功能,但也许我需要在模板的复选框数据绑定(bind)中执行某些操作?

此外,一旦我可以修改复选框并自动更新 View 模型和未读计数,那么将该更新发布回服务器(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
    }]
}

最佳答案

似乎您可以在 click 上执行函数(在 data-bind='click: function() {...}' 内)对于每个项目,根据选中的复选框的值递增或递减未读计数器。这样,您就不必循环遍历 currentList并以这种方式更新未读计数。

您还可以订阅 View 模型的 read显式属性并在 read 时执行您自己的代码更改(请参阅 observables documentation 中间的“显式订阅可观察量”)。

编辑:Here's一个用户描述如何使用具有可观察属性的项目设置可观察数组的线程。 Here这是作者(Steve Sanderson)提出的一个示例,演示了具有可观察属性的可观察数组。

使用这两种方法,您似乎都可以执行 AJAX 调用来 POST 回服务器。

更新:以下是如何实现此功能的示例:

$(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);
});

<强> Demo here .

注释:

  • 不使用 map 插件。但总体逻辑应该是相同的。
  • 如果 AJAX 调用失败,您可能应该在点击之前更新复选框的状态。
  • 您可以更新unreadCount通过调用 viewModel.unreadCount(<value>) 在 vi​​ewModel 中的任何位置属性.
  • 这是基于几个示例,特别是 this one 。这些复杂的示例特别令人大开眼界,并展示了您可以使用 KO 做的一些很酷的事情。

关于jquery - 如何修改 JSON 中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547316/

相关文章:

knockout.js - knockout 数组更改 - 可能的状态

javascript - 如何在满是行的表格上使表格行淡出

javascript - 滑动切换 [Jquery 函数] 不工作

javascript - MVC5 CRUD 最佳方法

javascript - 隐藏元素时, knockout 点击绑定(bind)不起作用

jquery - Amplifyjs 发布表单数据

javascript - 在 Knockout JS 中保存对 DOM 元素的引用的正确模式

javascript - 当鼠标移动缓慢时,Bootstrap 4 中的菜单消失

jquery - 使用自定义验证的 FileExtension Validation 会创建重复和无效的 data-* 属性

jquery - 在交替行上更改列表的方向