Asp.net mvc 4 淘汰JS视图刷新和过滤
我是个新手,所以请耐心点。我有一个数据表,我正试图从表的标题部分的文本框中动态筛选它。我只能在文本框中添加一个字符,然后数据被过滤,控件失去焦点。例如,我无法键入XX,因为当输入第一个X并且从文本框中删除光标时,过滤操作将启动并完成 这是我的灵感- 这是标记Asp.net mvc 4 淘汰JS视图刷新和过滤,asp.net-mvc-4,knockout.js,Asp.net Mvc 4,Knockout.js,我是个新手,所以请耐心点。我有一个数据表,我正试图从表的标题部分的文本框中动态筛选它。我只能在文本框中添加一个字符,然后数据被过滤,控件失去焦点。例如,我无法键入XX,因为当输入第一个X并且从文本框中删除光标时,过滤操作将启动并完成 这是我的灵感- 这是标记 // This where I'm filtering <thead> <tr data-bind="foreach: columnNames">
// 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>
看起来发生这种情况是因为您的self.columnNames是一个计算的可观察对象,它依赖于self.enrollments可观察对象。当应用筛选器时,self.enrollments observable会发生更改。当您的self.columnnamesobservable更新时,会发生重新绑定,所有内容都会重新呈现,您会因为DOM元素是新的而失去焦点 我将移动逻辑以在单独的函数中构建列:
function initColumns () {
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;
});
然后在初始化columnNames可观察数组时调用此函数
self.columnNames = ko.observableArray(initColumns());
否则你会陷入这个自我更新的循环地狱
基于fiddle的更新
好的,那么您要做的是删除self.filteredItems,并创建一个计算的可观察对象,如下所示:
self.filteredEnrollments = ko.computed(function () {
var filter = self.filters();
return 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;
});
});
而不是在html中,绑定到FiltereDenRolls而不是注册
<tbody data-bind="foreach: filteredEnrollments">
<tr>
<td data-bind="text: WinId"></td>
<td data-bind="text: EffectiveYear"></td>
<td data-bind="text: FileKeeperGroupId"></td>
</tr>
</tbody>
这样,您就不会更改您的注册可观察数组,因为该数组不会触发计算出的列名以重新绑定DOM。self.columnNames->是否有任何理由对其进行编译?它可以防止字段名被硬编码,但我可能100%错误。好吧,我看不到您的self.rollments在哪里填充。据我所知,你是根据注册中的第一个元素来构建专栏名的。按照我在回答中提出的方法来尝试,看看会发生什么。我认为你的逻辑是正确的,但我无法让它发挥作用。文本框不在那里,我的表也没有记录。还有,为什么我把-self.columnNames=ko.observearrayinitcolumns;?放在哪里很重要;???如果我把它放在虚拟机的顶部,我会得到一个数组错误。self.filteredItems中的filter变量是空的,所以它返回false。你能创建JSFIDLE吗?我应该可以,但我需要等到明天,因为它在代码中不是直接的。我很难提取正确的代码和数据放在小提琴中。然而,这把小提琴正是我想要做的-
<tbody data-bind="foreach: filteredEnrollments">
<tr>
<td data-bind="text: WinId"></td>
<td data-bind="text: EffectiveYear"></td>
<td data-bind="text: FileKeeperGroupId"></td>
</tr>
</tbody>