2014-11-24 61 views
0

我只是将一个可观察对象的列表绑定到一个HTML表格内的TR上。当用户选择一行(只能选择一行)时,我想从可观察数组中移除所选行或可观察对象。我有删除工作,但它完全无视该行是否被选中。我在每一行上使用一个标志来确定它们是否被检查,但是该值始终为真...即使您取消选中该行上的复选框,这也是为什么它会将它们全部删除。可有人请在下面的淘汰赛设置光棚...的研究和试验,但KO天只是恨我:(如何使用KnockoutJS从表格中删除选定的行

  <table class="accountGroups" id="tblAccountGroups"> 
      <tr> 
       <td width="150px;" style="font-weight: bold;">StandardAccountNo</td> 
       <td width="100px;" style="font-weight: bold;">Primary</td> 
       <td style="font-weight: bold;">Effective Date</td> 
       <td style="font-weight: bold;">End Date</td> 
      </tr> 
      <!-- ko foreach: NewAccountGroupDetails--> 
      <tr id="Model.NewAccountGroupDetails[0].AccountGroupName" rowindex="$index()" class="acctgrp-row" data-bind="click: $root.selectedRow"> 
       <td> 
        <div> 
         <input type="text" data-bind="value: StandardAccountNo, attr: {name: 'NewAccountGroupDetails[' + $index() + '].StandardAccountNo'}" /> 
        </div> 
       </td> 
       <td style="border:2px inset;border-color:gray;"> 
        <div style="text-align:center;"> 
         <input type="radio" data-bind="value: IsPrimary, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsPrimary'}" /> 
        </div> 
       </td> 
       <td> 
        <div style="width:115px;"> 
         <input type="text" data-bind="value: EffectiveDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EffectiveDate'}" readonly="readonly" /> 
        </div> 
       </td> 
       <td> 
        <div style="width:115px;"> 
         <input type="text" data-bind="value: EndDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EndDate'}" readonly="readonly" /> 
        </div> 
       </td> 
       <td> 
        <input type="hidden" data-bind="value: ContractType, attr: {name: 'NewAccountGroupDetails[' + $index() + '].ContractType'}" /> 
        <input type="hidden" data-bind="value: CompanyID, attr: {name: 'NewAccountGroupDetails[' + $index() + '].CompanyID'}" /> 
        <input type="hidden" data-bind="value: AccountGroupName, attr: {name: 'NewAccountGroupDetails[' + $index() + '].AccountGroupName'}" /> 
        <input type="checkbox" data-bind="checked: IsSelected, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsSelected'}" /> 
       </td> 
      </tr> 
      <!-- /ko --> 
     </table> 
    </div> 
</div> 
<br /> 
<div class="row"> 
    <div class="col-lg-2 col-sm-2">&nbsp;</div> 
    <div class="col-lg-2 col-sm-2" style="text-align:right;"> 
     <input type="button" value="New" data-bind="click: addNew" /> 
    </div> 
    <div class="col-lg-2 col-sm-2"> 
     <input type="button" value="Remove" data-bind="click: remove" /> 
    </div> 
    <div class="col-lg-3 col-sm-2">&nbsp;</div> 
    <div class="col-lg-2 col-sm-2"> 
     <input type="button" value="Save" id="btnSave" /> 
    </div> 
</div> 

JS

$(document).on('ready', function() { 
    ko.applyBindings(new AccountGroupViewModel()); 
}); 

    function AccountGroupViewModel() { 
    var viewModel = this; 

    //Convert Model property into observable array for KO 
    var rawList = '@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.NewAccountGroupDetails))'; 
    viewModel.NewAccountGroupDetails = ko.observableArray(convertJSONToKoObservableObject($.parseJSON(rawList))); 

    //Add properties to the vm and an empty ko object to the array 
    viewModel.NewAccountGroupDetails.push(newAccountGroupDetail()); 

    viewModel.addNew = function() { 
     viewModel.NewAccountGroupDetails.push(newAccountGroupDetail()); 
    } 

    viewModel.remove = function (row) { 
     viewModel.NewAccountGroupDetails.remove(function (item) { 
      return item.IsSelected(); 
     }); 
    } 
} 

function convertJSONToKoObservableObject(json) { 
    var ret = []; 
    $.each(json, function (i, obj) { 
     var newOBJ = {}; 
     for (prop in obj) { 
      newOBJ[prop] = ko.observable(obj[prop]); 
     } 
     ret.push(newOBJ); 
    }); 

    return ret; 
} 

function newAccountGroupDetail() { 
    this.StandardAccountNo = ko.observable(''); 
    this.IsPrimary = ko.observable(false); 
    this.EffectiveDate = ko.observable(new Date()); 
    this.EndDate = ko.observable(new Date()); 
    this.AccountGroupName = ko.observable($('#txtAccountGroupName').val()); 
    this.ContractType = ko.observable($('#ddlContractTypes').val()); 
    this.CompanyID = ko.observable($('#ddlCompany').val()); 
    this.IsSelected = ko.observable(false); 
    return this; 
} 
+0

你可以做一个简单的小提琴来重现问题了吗? – 2014-11-24 19:43:45

+0

我已经使用下面的注释更新了viewmodel的JS。它确实删除了一行,但问题在于它不会删除选定的行。如果您检查最后一行,请在5中删除它,它将删除所有行。如果你检查第一个4但不是第5个,它不会删除任何... WTH! – user1732364 2014-11-25 14:09:27

回答

0

你有几个失误这里

viewModel.selectedDetails = ko.computed(function() { 
     ko.utils.arrayForEach(viewModel.NewAccountGroupDetails(), function (row) { 
      row.IsSelected(true); 
     }); 
    }); 

这段代码row.IsSelected(true);实际上是集合IsSelected可观察值为真

从ObservableArray删除的项目,你应该使用类似:

viewModel.NewAccountGroupDetails.remove(function(item) { 
    return item.IsSelected(); 
}); 

而且以JSON值转换为视图模型,看看在mapping plugin

+0

问题是remove函数被绑定到顶级viewModel,它包含一个数组属性来填充页面。删除事件与此顶层关联,而不与列表中的项目关联。这意味着当remove被触发时,它将删除数组本身而不是该行,因为它不在该级别。让我知道你的想法.. – user1732364 2014-11-25 14:22:31