KnockoutJS:确保在添加新项目之前删除项目

时间:2016-12-09 17:39:47

标签: javascript knockout.js

我遇到了一个问题,我的数据在我的模型中没有正确更新。我在这里创造了一个小提琴:https://jsfiddle.net/wzhv5ghy/

在代码中,模型的所有更新都由此函数处理:

self.updateData = function (data) {         
    self.deliveryItems.removeAll(); // Sometimes our data won't replace correctly so lets kill everything here and then add it from scratch         

    if ( data != null )
        self.deliveryItems(data);               

    self.showLoadingNotice(false);

    // let the sorting plugin know that we made a update
    $("#deliveryItemsTable").trigger("update");

    //self.showTable(true);
    //console.log(data);

    // We moved this to functions.js since we use it multiple times
    //setupDeliveryItemsTable();        
};

我把它放在一个函数中,以便在使用各种JSON调用更新代码时更容易。

发生的问题是,页面中每隔一段时间就会显示旧数据(比如1000行),而下面的代码将显示1作为模型数据的计数:

<span data-bind="text: deliveryItems().length"></span>

我的猜测是这一行:     self.deliveryItems.removeAll();

未在此行之前运行     self.deliveryItems(数据);

如何在使用最新数据更新模型之前确保从模型和表格中删除所有项目?

1 个答案:

答案 0 :(得分:0)

就像@f_martinez指出我们的问题是jQuery Tablesorter插件和KO争取更新同一个表。为了解决这个问题,我最终使用下面的代码切换到KO tablesorting函数。排序似乎比Tablesorter版本慢,但它比有坏数据更好。

/*-------------------------------------------------------------------------*/
// Knockout.js Functions
/*-------------------------------------------------------------------------*/
ko.bindingHandlers.sort = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var asc = false;
        element.style.cursor = 'pointer';
        //console.log(element);

        element.onclick = function(){
            var value = valueAccessor();
            var prop = value.prop;
            var data = value.arr;

            asc = !asc;

            data.sort(function(left, right){
                var rec1 = left;
                var rec2 = right;

                if(!asc) {
                    rec1 = right;
                    rec2 = left;
                }

                var props = prop.split('.');
                for(var i in props){
                    var propName = props[i];
                    var parenIndex = propName.indexOf('()');
                    if(parenIndex > 0){
                        propName = propName.substring(0, parenIndex);
                        rec1 = rec1[propName]();
                        rec2 = rec2[propName]();
                    } else {
                        rec1 = rec1[propName];
                        rec2 = rec2[propName];
                    }
                }

                return rec1 == rec2 ? 0 : rec1 < rec2 ? -1 : 1;
            });
        };
    }
};

以下是表格本身的代码:

    <div class="alert alert-info" data-bind="visible: showLoadingNotice">
        Loading...
    </div>
    <table class="table table-striped table-bordered table-hover" id="deliveryItemsTable" data-bind="visible: showTable">
        <thead> 
            <tr class="title1">
                <td colspan="100%">Delivery Items ( <span data-bind="text: deliveryItems().length"></span> )</td>
            </tr>
            <tr class="title2">
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'created_on' }">Created On</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'company_name' }">Company</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'product_number_company' }">Item Number</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'client_phone_number' }">Phone Number</th>
                <th data-bind="sort: { arr: deliveryItems, prop: 'price_to_display' }">Price</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'location' }">Location</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'notes' }">Notes</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'delivered_by_text' }">Delivery Driver</th>
                <th class="header" data-bind="sort: { arr: deliveryItems, prop: 'status_labels' }">Status</th>
                <th class="header nowrap"></th>
            </tr>
        </thead>
        <tbody data-bind="foreach: deliveryItems">
            <tr data-bind="attr: {id: 'row_' + id }">
                <td data-bind="text: created_on"></td>
                <td data-bind="text: company_name"></td>
                <td data-bind="text: product_number_company"></td>
                <td data-bind="text: client_phone_number"></td>
                <td data-bind="text: formatCurrency(price_to_display)"></td>
                <td>
                    <span data-bind="text: location, attr: {id: 'edit-delivery_items-' + id + '_location' }"></span>
                    <button data-bind="click: $root.editLocation, visible: $root.canEdit" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
                </td>
                <td>
                    <span data-bind="text: notes, attr: {id: 'edit-delivery_items-' + id + '_notes' }"></span>
                    <button data-bind="click: $root.editNotes, visible: $root.canEdit" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
                </td>
                <td>
                    <span data-bind="text: delivered_by_text, attr: {id: 'edit_select-delivery_items-' + id + '_delivered_by' }"></span>
                    <button data-bind="click: $root.editDeliveryDriver, visible: $root.canEdit" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
                </td>                   
                <td data-bind="html: status_labels"></td>
                <td class="center"><span class="btn-group">
                    <button data-bind="click: $root.markAsDelivered, visible: $root.canMarkComplete" class="btn btn-default" title="Mark as delivered"><i class="glyphicon glyphicon-check"></i></button>
                    <a data-bind="attr: {href: 'index.php?action=editDeliveryItem&amp;id=' + id }, visible: $root.canEdit" class="btn btn-default" title="Edit"><i class="glyphicon glyphicon-edit"></i></a> 
                </span></td>
            </tr>
        </tbody>
    </table>
    <div class="alert alert-info" data-bind="visible: showLoadingNotice">
        Loading...
    </div>
    <div id="deliveryItemsTableUpdateNotice"></div>