【发布时间】:2014-12-10 16:56:46
【问题描述】:
我对 Knockout 有点陌生,所以请耐心等待。我有一个数据表,我试图从表头部分的文本框中动态过滤。我只能在文本框中添加一个字符,然后过滤数据并且控件失去焦点。例如,我无法输入“XX”,因为当输入第一个“X”并且光标从文本框中移除时,过滤操作开始并完成。
这是我的灵感 - http://jsfiddle.net/Xpx7f/20/
这是标记
// This where I'm filtering
<thead>
<tr data-bind="foreach: columnNames">
<td>
// why isn't this "data-bind="textInput: filters"?
// the observable name is filters not filter
<input type='text' data-bind="textInput: filter" />
</td>
</tr>
</thead>
<tbody data-bind="foreach: enrollments">
<tr>
<td data-bind="text: WinId"></td>
<td data-bind="text: EffectiveYear"></td>
<td data-bind="text: FileKeeperGroupId"></td>
</tr>
</tbody>
这是淘汰赛
var viewModel = (function(){
self = this;
self.enrollments = ko.observableArray([]);
self.filters = ko.observableArray([]);
self.filteredItems = ko.computed(function () {
var filter = self.filters();
var enrollments = ko.utils.arrayFilter(self.enrollments(), function (item) {
for (var col in filter) {
var v = (item[col] || '').toString(); // column value
var f = filter[col]; // what's typed in header
if (v.lastIndexOf(f, 0) === 0) return true;
}
return false;
});
if(enrollments.length > 0)
{
self.enrollments(enrollments);
}
else{
return self.enrollments();
}
});
var subscriptions = [];
self.columnNames = ko.computed(function () {
ko.utils.arrayForEach(subscriptions, function (s) { s.dispose(); });
subscriptions = [];
if (self.enrollments().length === 0) return [];
var props = [];
var obj = self.enrollments()[0];
for (var name in obj) {
var p = { name: name, filter: ko.observable('') };
subscriptions.push(p.filter.subscribe(filterOnChanged, p));
props.push(p);
}
return props;
});
var filterOnChanged = function (value) {
var filters = self.filters();
filters[this.name] = value;
self.filters(filters);
};
});
$(document).ready(function(){
var vm = new viewModel();
vm.getRecords();
ko.applyBindings(viewModel);
});
【问题讨论】:
-
self.columnNames -> 有什么理由让它被计算?
-
它可以防止字段名称被硬编码,但我可以 100% 错误
-
好吧,我没有看到您的 self.enrollments 的填充位置。据我了解,您根据注册中的第一个元素构建您的 columnNames。
-
按照我在答案中建议的方式尝试一下,看看会发生什么。