我正在尝试实现一个通用的ASP.net MVC视图。 UI应显示从服务器加载数据(基本上是字符串列表)的可用和选定项目的列表。用户可以对列表进行更改,即可以从可用项目列表中选择新项目,也可以从所选列表中删除项目。
我想使用KnockoutJS来利用绑定。
我设法完成所有工作,除了在可用列表中初始化视图时将所选项目显示为已选中。例如。 As Shown Here
我尝试了各种选项(using template (closest to what I want to achieve),Checked attr,possible options),问题是如果我设法显示项目检查了一些其他功能中断。尝试定义一个模板,但无法让它在我的情况下工作。
HTML:
<div class='moverBoxOuter'>
<div id='contactsList'>
<span data-bind="visible: availableItems().length > 0">Available countries: </span>
<ul data-bind="foreach: availableItems, visible: availableItems().length > 0">
<li>
<input type="checkbox" data-bind="checkedValue: $data, checked: $root.selectedItems" />
<span data-bind="text: title"></span>
</li>
</ul>
<span data-bind="visible: selectedItems().length > 0">Selected countries: </span>
<ul data-bind="foreach: selectedItems, visible: selectedItems().length > 0">
<li>
<span data-bind="text: title"></span>
<a href="#" data-bind="click: $parent.removeItem">Delete</a>
</li>
</ul>
</div>
JS:
var initialData = [
{
availableItems: [
{ title: "US", isSelected: true },
{ title: "Canada", isSelected: false },
{ title: "India", isSelected: false }]
},
{
selectedItems: [
{ "title": "US" },
{ "title": "Canada" }
]
}
];
function Item(titleText, isSelected) {
this.title = ko.observable(titleText);
this.isSelected = ko.observable(isSelected);
}
var SelectableItemViewModel = function (items) {
// Data
var self = this;
self.availableItems = ko.observableArray(ko.utils.arrayMap(items[0].availableItems, function (item) {
return new Item(item.title, item.isSelected);
}));
self.selectedItems = ko.observableArray(ko.utils.arrayMap(items[1].selectedItems, function (item) {
return new Item(item.title, item.isSelected);
}));
// Operations
self.selectItem = function (item) {
self.selectedItems.push(item);
item.isSelected(!item.isSelected());
};
self.removeItem = function (removedItem) {
self.selectedItems.remove(removedItem);
$.each(self.availableItems, function (item) {
if (item.title === removedItem.title) {
item.isSelected = false;
}
});
};
}
var vm = new SelectableItemViewModel(initialData);
$(document).ready(function () {
ko.applyBindings(vm);
});
请你帮帮忙,请看下面的jsfiddle:
http://jsfiddle.net/sbirthare/KR4a6/6/
**更新:跟进以下问题**
其后续问题:
我需要在同一个用户界面上添加一个组合框,例如对于美国州。可用的项目是县,根据用户选择状态组合我需要过滤县。我使用AJAX从服务器获取数据并且所有成功但是显示的列表没有刷新。我期待正确的绑定设置,如果我们在viewmodel中更改observable数组,UI应该更改。我尝试强制更改为availableItems,但它只显示所有项目。请查看您是否可以在下面的代码中发现我正在更新ViewModel observable数组的问题。
function multiselect_change() {
console.log("event: openmultiselect_change");
var selectedState = $("#stateDropdownSelect").val();
var propertyName = $("#PropertyName").val();
var searchId = @Model.SearchId;
var items;
var model = { propertyName: propertyName, searchId: searchId, stateName: selectedState };
$.ajax({
url: '@Url.Action("GetFilterValues", "Search")',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
data: JSON.stringify(model)
})
.success(function(result) {
debugger;
items = JSON.parse(result);
vm.availableItems(items.AvailableItems);
//vm.availableItems.valueHasMutated();
//var item = document.getElementById('availableItemId');
//ko.cleanNode(item);
//ko.applyBindings(vm, item);
vm.filter(selectedState);
})
.error(function(xhr, status) {
alert(status);
});
}
答案 0 :(得分:1)
正如user3426870所提到的,您需要将传递给检查绑定的值更改为boolean。
<input type="checkbox" data-bind="checkedValue: $data, checked: isSelected" />
另外,我认为您不需要在初始数据中使用selectedItems。
相反,在viewModel中,您可以执行以下操作:
self.selectedItems = ko.computed(function() {
return ko.utils.arrayFilter(self.availableItems(), function (item) {
return item.isSelected();
});
});
答案 1 :(得分:0)
这是因为您为绑定checked
提供了一个数组,而它应该是一个与true
或false
(如undefind
或空字符串)相当的值。
我会使用函数检查$data
是否在您的数组中,并为绑定返回一个布尔值。
类似的东西!