我创建了一个具有可观察属性的ViewModel。我将此数组绑定到ul
HTML元素,如下所示:
<ul id="sortable"
data-bind="template: { name: 'parameterTemplate',
foreach: parameters },
visible: parameters().length > 0"
style="width: 100%">
</ul>
我的模板是:
<script type="text/html" id="parameterTemplate">
<li class="ui-state-default parameterItem">
<input type="checkbox" data-bind="checked: isRequired" />
Name:
<input data-bind="value: name " />
Type:
<input data-bind="value: type " />
Size:
<input data-bind="value: size " />
<a href="#" data-bind="click: remove">Delete</a>
</li>
</script>
我正在使用jQuery的可拖动和可排序资源来重新排序列表的元素。这意味着当用户更改元素的顺序时,显然ko databind不会被更改,因为jQuery不知道敲除存在。
碰巧我希望我的parameters
按照用户配置的顺序保存。所以我的方法是通过jQuery选择li
HTML元素,得到一个数组(var items = $(".parameterItem");
)。对于items
中的每个项目,我如何获得与li
HTML元素相关联的数据绑定挖空元素?
有可能吗?
我的视图模型:
function parameter(parameterName, parameterType, parameterSize, descriptive, defaultValue, isRequired, ownerViewModel) {
this.name = ko.observable(parameterName);
this.type = ko.observable(parameterType);
this.size = ko.observable(parameterSize);
this.label = ko.observable(parameterName);
this.descriptive = ko.observable(descriptive);
this.defaultValue = ko.observable(defaultValue);
this.descriptive = ko.observable(descriptive);
this.isRequired = ko.observable(isRequired);
this.ownerViewModel = ownerViewModel;
this.remove = function () {
ownerViewModel.parameters.remove(this)
};
}
function excelLoaderViewModel() {
this.parameters = ko.observableArray([]);
this.newParameterName = ko.observable();
this.newParameterType = ko.observable();
this.newParameterSize = ko.observable();
this.newParameterDescriptive = ko.observable();
this.newParameterIsRequired = ko.observable();
this.newParameterDefaultValue = ko.observable();
this.systemName = ko.observable();
this.addParameter = function () {
this.parameters.push(
new parameter(
this.newParameterName()
, this.newParameterType()
, this.newParameterSize()
, this.newParameterDescriptive()
, this.newParameterDefaultValue()
, this.newParameterIsRequired()
, this));
this.newParameterName("");
this.newParameterType("");
this.newParameterSize("");
this.newParameterIsRequired(false);
this.newParameterDefaultValue("");
}
var myVM = new excelLoaderViewModel();
ko.applyBindings(myVM);
答案 0 :(得分:5)
您最好的选择是使用自定义绑定来保持observableArray在拖放时与您的元素保持同步。
这是我刚才写的post。
这是一个适用于jQuery模板的自定义绑定:
//connect items with observableArrays
ko.bindingHandlers.sortableList = {
init: function(element, valueAccessor) {
var list = valueAccessor();
$(element).sortable({
update: function(event, ui) {
//retrieve our actual data item
var item = ui.item.tmplItem().data;
//figure out its new position
var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
//remove the item and add it back in the right spot
if (position >= 0) {
list.remove(item);
list.splice(position, 0, item);
}
}
});
}
};
以下是正在使用的示例:http://jsfiddle.net/rniemeyer/vgXNX/
如果您在没有jQuery模板(或使用)的情况下使用Knockout 1.3 beta,那么您可以使用1.3中提供的新tmplItem
方法替换ko.dataFor
行:
//connect items with observableArrays
ko.bindingHandlers.sortableList = {
init: function(element, valueAccessor) {
var list = valueAccessor();
$(element).sortable({
update: function(event, ui) {
//retrieve our actual data item
var item = ko.dataFor(ui.item[0]);
//figure out its new position
var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
//remove the item and add it back in the right spot
if (position >= 0) {
list.remove(item);
list.splice(position, 0, item);
}
}
});
}
};