我有复选框列表,单击任何复选框时我需要获取所有选中的复选框。为此,我调用 java 脚本函数“ChangeColumnSelection”。
问题是,单击的复选框不会立即更新 View 模型。当我单击下一个文本框时,我看到之前的复选框值已在 View 模型中更新。
<ul class="list-group" data-bind="foreach: SelectionColumnList">
<li class="list-group-item">
<input type="checkbox" data-bind="attr: {onclick: 'javascript:ChangeColumnSelection(\'' + ColumnID + '\')'}, checked: IsSelected"
class="pull-xs-left push-down rightmargin" />
<span data-bind="text: ColumnName"></span>
</li>
</ul>
更新:
我的 View 模型是
var dynamicGridViewModel = {
SelectionColumnList: ko.observableArray([])
};
selectionInfo.ColumnID = columnInfo.ColumnID;
selectionInfo.ColumnName = columnInfo.ColumnName;
selectionInfo.DisplayOrder = columnInfo.DisplayOrder;
selectionInfo.SortType = 'None';
selectionInfo.IsSelected = true;
dynamicGridViewModel.SelectionColumnList.push(selectionInfo);
最佳答案
您不需要 onclick
事件。您只需使用 checked binding 即可实现此目的:
var array = [{
ColumnID: 1,
ColumnName: "ColumnName 1"
}, {
ColumnID: 2,
ColumnName: "ColumnName 2"
}]
var viewModel = function() {
var self = this;
self.SelectionColumnList = ko.observableArray(array);
// no need to populate the array manually. Knockout will take care of it
self.chosenItems = ko.observableArray();
// every time chosenItems array changes, subscribe callback function gets triggered
self.chosenItems.subscribe(function() {
console.log(self.chosenItems());
})
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul class="list-group" data-bind="foreach: SelectionColumnList">
<li class="list-group-item">
<input type="checkbox" data-bind="checkedValue: ColumnID, checked: $parent.chosenItems" />
<span data-bind="text: ColumnName"></span>
</li>
</ul>
此处,ColumnId
设置为 checkbox
输入的值。因此,chosenItems
数组将是选定ColumnId
的数组。
Knockout 的伟大之处在于,它不仅允许 primitive types例如 checkedValue
的字符串、数字或 boolean 值,但也包括对象。如果您希望将整个Column
对象填充到chosenItems
中,那么您可以像这样设置checkedValue
:
<input type="checkbox" data-bind="checkedValue: $data, checked: $parent.chosenItems" />
如果您想在更改任何复选框的状态时执行某些操作,您可以在subscribe
内执行该操作。打回来。每次数组更改时都会触发此函数。
(此外,添加 click binding 的正确方法是 data-bind="click: clickFunction"
)
更新:
您正在使用对象文字作为您的 View 模型。我建议您创建 viewModel 函数并使用 new运算符(operator)。如果您想将 checked
绑定(bind)到 Column
的 boolean 属性,那么您可以创建一个 computed属性并订阅
该计算属性:
var columns = [{
ColumnID: 1,
ColumnName: "ColumnName 1",
IsSelected: false
}, {
ColumnID: 2,
ColumnName: "ColumnName 2",
IsSelected: true
}];
var viewModel = function() {
var self = this;
self.SelectionColumnList = ko.observableArray([]);
// this property has the selected ColumnIds
self.selectedItems = ko.computed(() => {
// If you're using ES6 systax
// return self.SelectionColumnList()
// .filter(column => column.IsSelected())
// .map(column => column.ColumnID);
// out of the columns, get the ColumnIds with IsSelected as true
return self.SelectionColumnList()
.filter(function(column) {
return column.IsSelected();
})
.map(function(column) {
return column.ColumnID
});
});
// gets triggered everytime checkbox is checked/unchecked
self.selectedItems.subscribe(function() {
console.log(self.selectedItems());
});
}
// create a new instance of the viewmodel
var dynamicGridViewModel = new viewModel();
// loop through the columns and populate the observableArray
columns.forEach(function(columnInfo) {
var selectionInfo = {};
selectionInfo.ColumnID = columnInfo.ColumnID;
selectionInfo.ColumnName = columnInfo.ColumnName;
// this property must be an observable
selectionInfo.IsSelected = ko.observable(columnInfo.IsSelected);
dynamicGridViewModel.SelectionColumnList.push(selectionInfo);
})
ko.applyBindings(dynamicGridViewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<ul class="list-group" data-bind="foreach: SelectionColumnList">
<li class="list-group-item">
<input type="checkbox" data-bind="checked: IsSelected" />
<span data-bind="text: ColumnName"></span>
</li>
</ul>
关于javascript - knockout 中的复选框 onclick 不会更新 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47331161/