从挖空可观察数组中删除表中的选定行
Remove selected row in table from Knockout observable array
好的,我有工作代码可以通过选中的复选框删除选定的行。但是,我遇到了强制在任何给定时刻只能检查其中一个单选按钮的问题。我的第一个方法是将单击事件绑定到每个单选按钮,如果它被单击,它将循环遍历可观察数组并标记所有"false"。然后,它只是将触发事件的项的标志翻转为 true。我知道这不是最好的方法,但我对淘汰赛缺乏光彩的知识迫使我走上这条路。即使此方法不适用于 ATM。谁能阐明我做错了什么或如何正确连接它?
表的 html
<table class="accountGroups information" id="tblAccountGroups">
<tr>
<td width="125px;" style="font-weight: bold;">StandardAccountNo</td>
<td width="125px;" style="font-weight: bold; text-align: center;">Primary</td>
<td style="font-weight: bold;">Effective Date</td>
<td style="font-weight: bold;">End Date</td>
<td style="font-weight: bold;">Remove</td>
</tr>
<!-- ko foreach: NewAccountGroupDetails-->
<tr id="Model.NewAccountGroupDetails[0].AccountGroupName" class="acctgrp-row">
<td>
<div>
<input style="width: 100%;" data-bind="value: StandardAccountNo, attr: {name: 'NewAccountGroupDetails[' + $index() + '].StandardAccountNo'}" />
</div>
</td>
<td>
<div style="text-align:center;">
<input style="width:100%;" type="radio" data-bind="value: IsPrimary, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsPrimary'}, click: $parent.markIsPrimary" />
</div>
</td>
<td>
<div>
<input style="width:125px;" class="datepicker" data-bind="value: EffectiveDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EffectiveDate'}" readonly="readonly" />
</div>
</td>
<td>
<div>
<input style="width:125px;" class="datepicker" data-bind="value: EndDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EndDate'}" readonly="readonly" />
</div>
</td>
<td>
<div style="text-align:center;">
<input type="checkbox" data-bind="checked: markedForDeletion, attr: {name: 'NewAccountGroupDetails[' + $index() + '].MarkedForDeletion'}" />
</div>
</td>
</tr>
<!-- /ko -->
</table>
下面的JS为页面提供支持
////VIEW MODEL FOR KNOCKOUT////
var Detail = function () {
this.StandardAccountNo = ko.observable('');
this.IsPrimary = ko.observable(false);
this.EffectiveDate = ko.observable(formattedDate(new Date()));
this.EndDate = ko.observable(formattedDate(new Date()));
this.markedForDeletion = ko.observable(false);
};
var ViewModel = function () {
var rawList = '@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.NewAccountGroupDetails))';
this.NewAccountGroupDetails = ko.observableArray(convertJSONToKoObservableObject($.parseJSON(rawList)));
this.NewAccountGroupDetails.push(new Detail());
this.deleteMarkedItems = function () {
this.NewAccountGroupDetails.remove(function (item) {
return item.markedForDeletion();
});
};
this.markIsPrimary = function () {
for (i = 0; this.NewAccountGroupDetails().length > 0; i++) {
this.NewAccountGroupDetails[i].IsPrimary(false);
}
return item.IsPrimary(true);
};
this.addNew = function () {
this.NewAccountGroupDetails.push(new Detail());
$('.datepicker').each(function (i, obj) {
$(obj).datepicker({ changeYear: true, changeMonth: true });
});
}
};
ko.applyBindings(new ViewModel());
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;
}
一旦我让页面按照我想要的方式工作,我将研究语法改进,例如数组的 ko 映射库。
在视图模型中,按如下所示构造删除按钮:
viewModel.remove = function (row) {
console.log(row);
viewModel.NewAccountGroupDetails.remove(row);
};
现在,当前上下文作为第一个参数传递给 KNOCKOUT 中的任何回调。因此,如果添加带有 data-bind="click: $parent.remove"
的按钮,它将使用行上下文调用 viewModel.remove
函数。
<tr ...>
...
<td>
<button data-bind="click: $parent.remove">Remove</button>
</td>
</tr>
我需要一些额外的信息,但让我给你看一个例子,并给你一些建议:
一、建议:
- 为了在具有可观察属性的对象中转换您的常规对象,您可以使用挖空映射插件。
- 您可以省略解析 JSON 的步骤。您可以简单地将 JSON 分配给 var,如下所示:
var JSON=*your serialized JSON*;
(不要忘记末尾的分号。 - 而不是在数据绑定中包含如此多的代码,如下所示:
NewAccountGroupDetails['+ $index() + '].EndDate
,在视图模型本身上执行此计算,使用名为的计算,例如EndDateName
- 视图模型应包含可观察
selectedRow
。当用户选择该行时,将该行放在那里,您可以使用计算的可观察量来确定某一行是否为所选行。 - 考虑到您可以绑定调用代码中函数的事件,并且此事件携带与发起事件的 DOM 对象关联的数据。 也就是说,如果用户点击与帐户组详细信息关联的行,您将在事件中收到该行。
示例 2:
// Instead of:
var viewModelJson = '[{"name": "Pepe"},{"name":"Juan"}]';
var viewModel = $.parseJSON(viewModelJson);
// Do this directly:
var people = [{"name": "Pepe"},{"name":"Juan"}];
由于 4 和 5 不是同时清楚的,因此这是您想要实现的目标的简单示例。
<ul data-bind="foreach: people">
<li data-bind="text: name, click: $root.select,
css: {red: $data == $root.selectedPerson()}" >
</li>
</ul>
请注意,当条件为 true 时,将应用 css 类red
。条件是绑定到当前行的值与可观察selectedPerson
中的值相同。
这是相应的JavaScript(记得引用淘汰映射!!
var people = [{"name": "Pepe"},{"name":"Juan"}];
var PeopleModel = function(people) {
var self = this;
self.selectedPerson = ko.observable(); // This will hold the selected person
self.people = ko.mapping.fromJS(people); // Note ko.mapping!!
self.select = function(person) { // event receives the current data as 1st param
self.selectedPerson(person);
}
self.delete = function(person) {
// find de index of person and remove 1 item from that index
self.people.splice(self.people.indexOf(person),1);
}
return self;
};
var peopleModel = new PeopleModel(people);
ko.applyBindings(peopleModel);
你可以在这里运行jsfiddle。
如果将单击绑定更改为调用$root.delete
而不是$root.select
,则在单击该绑定时,您将看到该人员从列表中消失。当然,您可以添加一个额外的元素来执行此操作。
注意:您可以在KNOCKOUT JS网站上阅读有关单击绑定的文档。
最后一个建议:最好使用 Web API 或返回 JsonResult 的方法直接从服务器恢复数据,并将 js 保存在单独的文件中。
更新一点点模式代码。
您可以添加此 HTML:
<input type="button" data-bind="click: removeSelected" value="removeSelected"/>
而视图模型中的这种方法:
self.removeSelected = function() {
if (self.selectedPerson()) {
self.delete(self.selectedPerson());
}
};
如果这样做,则在单击按钮时,如果有选定的项目,它将从列表中删除。
更新:另一个更完整的示例
在这里,您有一个更完整的示例,在此小提琴中,其中包括以下代码:
.CSS:
body {
font-family: Arial;
}
.container {
margin: 10px 0;
border: solid 1px #ABF;
}
.container > div {
padding: 4px;
border: solid 1px #ABF;
position: relative;
}
.selected {
border: solid 1px #00A;
color: #00A;
background-color: #BCF;
}
.HTML:
<div data-bind="foreach: people" class="container">
<div data-bind="click: $root.select,
css: {selected: $data == $root.selectedPerson()}" >
<!-- ko text: name --><!-- /ko -->
<input type="button" value="Remove"
style="right:3px;top:2px; position:absolute;"
data-bind="click:$root.delete"/>
</div>
</div>
<div data-bind="visible: selectedPerson()" >
<input type="button" data-bind="click: removeSelected" value="Remove Selected"/>
<input type="button" data-bind="click: unSelect" value="Deselect"/>
</div>
<div data-bind="visible: selectedPerson()" class="container">
<div>
Selected: <!-- ko text: selectedPerson().name --><!-- /ko -->
</div>
</div>
JavaScript:
var people = [{"name": "Pepe"},{"name":"Juan"},{"name":"Luis"},{"name":"Adolfo"}];
var PeopleModel = function(people) {
var self = this;
self.selectedPerson = ko.observable(); // This will hold the selected person
self.people = ko.mapping.fromJS(people); // Note ko.mapping!!
self.select = function(person) { // The event receives the current data as parameter
self.selectedPerson(person);
};
self.delete = function(person) {
// find de index of person and remove (splice) it from the observable array
self.people.splice(self.people.indexOf(person),1);
self.selectedPerson(null);
}
self.removeSelected = function() {
if (self.selectedPerson()) {
self.delete(self.selectedPerson());
}
};
self.unSelect = function() {
self.selectedPerson(null);
}
return self;
};
var peopleModel = new PeopleModel(people);
ko.applyBindings(peopleModel);
选择所选行时尝试临时保存该行
function AccountGroupViewModel() {
var viewModel = this;
viewModel.selectedRow = null;
// ...
viewModel.selectRow = function (data) {
// ...
viewModel.selectedRow = data;
}
viewModel.remove = function () {
// ...
if (viewModel.selectedRow != null) {
this.NewAccountGroupDetails.remove(viewModel.selectedRow);
}
}
}
- 如何从Knockout validation中的可观察项中删除验证规则[extenders]
- 对可观察数组foreach的更新删除了格式化knockoutjs
- 突变观察者未能检测到元素's删除dom
- 删除 DOM 事件观察器
- 无法使用 Knockoutjs 从可观察数组中删除项目
- 删除和编辑挖空可观察数组中的项目
- 从 Knockoutjs 中的可观察数组中删除项目
- 观察通过 chrome devtools 添加/删除节点时的 DOM 突变
- 从可观察数组列表中删除元素
- Knockout JS + JQuery UI - 在重新排序后从可观察数组中删除项目的问题
- Angularjs - $scope.$destroy 不会删除观察者
- 从路由转换不会删除 Ember.js 中退出路由的控制器观察器
- KnockoutJS从可观察数组中删除项目.Item 是 ul 中的列表项,由 foreach 生成
- 如何从可观察对象数组中删除项目
- 从挖空可观察数组中删除表中的选定行
- 如何清除/删除Knockout.js中的可观察绑定
- 用于修改从子视图模型在父视图上可观察到的删除的模式
- KnockoutJS.Mapping.FromJS-可观察数组-删除不起作用
- 比较knockout可观察数组,并从数组中删除任何具有match id的对象
- 在Knockout可观察数组订阅函数中,可以确定添加或删除了哪些元素吗?