Skip to main content
 首页 » 编程设计

jquery之使用 jquery.dataTables 从 observableArray 中删除项目后 UI 未更新

2026年09月08日2itcoder

我正在使用 jquery.dataTables 和 knockout js 将数据绑定(bind)到表。

从 observableArray 中删除项目后,UI 不会更新。因为我将数据绑定(bind)到 jquery.Datatable,所以可以重新初始化表;因此,我通过调用 TableManaged.init(); 方法重新初始化表,但它生成警告无法重新初始化数据表。

下面是我的代码。

function PatientVM(vm) { 
  self.MDSPatientId = ko.observable(vm.MDSPatientId()); 
  self.PatientNumber = ko.observable(vm.PatientNumber()); 
  self.PrescribingDay = ko.observable(vm.PrescribingDay()); 
  self.OneWeekItems = ko.observable(vm.OneWeekItems()); 
  self.DeliveryDay = ko.observable(vm.DeliveryDay()); 
  self.IsActive = ko.observable(vm.IsActive()); 
  self.WeekColor = ko.observable(vm.WeekColor()); 
  self.PatientName = ko.observable(vm.PatientName()); 
  self.FullAddress = ko.observable(vm.FullAddress()); 
} 
 
function Patients(vm) { 
  var self = this; 
  self.PatientList = ko.observableArray(); 
 
  if (vm.PatientList() != null) { 
    for (i = 0; i < vm.PatientList().length; i++) { 
      var p = new PatientVM(vm.PatientList()[i]); 
      self.PatientList.push(p); 
    } 
  } 
 
  self.DeletePatient = function(patient) { 
    var result = confirm("Want to delete?"); 
    if (result) { 
      $.ajax({ 
        url: '@Url.Action("DeleteMDSPatient", "Patient")', 
        cache: false, 
        type: 'GET', 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        data: { 
          'MDSPatientId': patient.MDSPatientId() 
        }, 
        success: function(response) { 
          if (response.Result == 3) { 
            self.PatientList.remove(patient); 
            ShowToastMessage("Patient has been deleted successfully", "Success", true); 
          } 
        }, 
        error: function(errorThrown) {} 
      }); 
    } 
  } 
} 
 
$(document).ready(function() { 
  ko.applyBindings(new Patients(ko.mapping.fromJS(@Html.Raw(JsonConvert.SerializeObject(Model))))); 
  App.init(); 
  TableManaged.init(); 
});
<table class="table table-striped table-bordered table-hover" id="sample_3" style="line-height:22px;table-layout:fixed;overflow-x:hidden;"> 
  <thead> 
    <tr style="background-color:#348fe2"> 
      <th style="width:5%;text-align:center"> 
        <span class="showellipses">Active Patient</span> 
      </th> 
      <th style="width:10%"><span>Name</span> 
      </th> 
      <th style="width:20%"><span class="showellipses">Address</span> 
      </th> 
      <th style="width:10%"><span class="showellipses">PrescribingDay</span> 
      </th> 
      <th style="width:5%"><span class="showellipses">No. of items in four week</span> 
      </th> 
      <th style="width:10%"><span class="showellipses">Assembly Week</span> 
      </th> 
      <th style="width:10%"><span>Delivery Day</span> 
      </th> 
      <th style="width:5%">Action</th> 
    </tr> 
  </thead> 
  <tbody data-bind="foreach:PatientList"> 
    <tr class="odd gradeX"> 
      <td style="text-align:center"> 
        <input type="checkbox" data-bind="checked:IsActive, click:ChangePatientStatus" class="checkboxes" /> 
      </td> 
      <td> 
        <span class="showellipses" data-bind="text:PatientName"></span> 
      </td> 
      <td> 
        <span class="showellipses" data-bind="text:FullAddress"></span> 
      </td> 
      <td> 
        <span data-bind="text:PrescribingDay"></span> 
      </td> 
      <td class="center"> 
        <span data-bind="text:OneWeekItems"></span> 
      </td> 
      <td> 
        <span data-bind="text:WeekColor"></span> 
      </td> 
      <td> 
        <span data-bind="text:DeliveryDay"></span> 
      </td> 
      <td> 
        <a title="Edit" style="text-decoration:none" class="fa fa-edit" data-bind="attr: { 'href': '@Url.Action(" PatientView ", "Patient ")?MDSPatientId=' + MDSPatientId()}"></a>&nbsp;| 
        <a title="Delete" style="text-decoration:none" class="fa fa-trash-o" data-bind="click:$parent.DeletePatient"></a> 
      </td> 
    </tr> 
  </tbody> 
</table>

请您参考如下方法:

这是他们文档中的一个示例 link .

您需要一个额外的步骤来通知 jquery 插件更新表。 基本上,您需要订阅数组更改并使删除的行无效。 他们建议使用助手来订阅可观察数组,如下所示:

// Helper function so we know what has changed 
// http://stackoverflow.com/questions/12166982 
ko.observableArray.fn.subscribeArrayChanged = function(addCallback, deleteCallback) { 
    var previousValue = undefined; 
    this.subscribe(function(_previousValue) { 
        previousValue = _previousValue.slice(0); 
    }, undefined, 'beforeChange'); 
    this.subscribe(function(latestValue) { 
        var editScript = ko.utils.compareArrays(previousValue, latestValue); 
        for (var i = 0, j = editScript.length; i < j; i++) { 
            switch (editScript[i].status) { 
                case "retained": 
                    break; 
                case "deleted": 
                    if (deleteCallback) 
                        deleteCallback(editScript[i].value); 
                    break; 
                case "added": 
                    if (addCallback) 
                        addCallback(editScript[i].value); 
                    break; 
            } 
        } 
        previousValue = undefined; 
    }); 
}; 

然后您需要订阅并响应数组更改:

self.PatientList.subscribeArrayChanged( 
        function ( addedItem ) { 
            dt.row.add( addedItem ).draw(); 
        }, 
        function ( deletedItem ) { 
            var rowIdx = dt.column( 0 ).data().indexOf( deletedItem.id ); 
            dt.row( rowIdx ).remove().draw(); 
        } 
    ); 

这是一个plunk带有完整的示例。