我正在使用KnockoutJs来构建搜索列表,代码如下:
HTML:
<input type="search" id="search-bar" placeholder="Enter a name" data-bind="value:query,valueUpdate: 'keyup'">
<div id="list" data-bind='template: {foreach: name}'>
<li data-bind='text $data'></li>
</div>
Js搜索功能的一部分:
this.name = ko.observable('');
this.query = ko.observable('');
this.search = function (value) {
self.name([]);
for (var x in name) {
if (name[x].toLowerCase().indexOf(value.toLowerCase()) >= 0) {
self.name.push(name[x]);
}
}
}
this.query.subscribe(self.search);
使用$ .get从不同的URL检索数据(2-D列表)然后解析,然后我将解析数据的每个第一个条目(arsed_data [i] [0])分配为名称observable码。
该列表意味着根据搜索框条目过滤内容,并且它最初显示所有名称,但是只要我在搜索框中键入内容,名称列表就会变空,可能的原因是什么?一种解决方法吗?
答案 0 :(得分:1)
如果你想直接在observable上使用push
之类的数组方法,你需要将它设为observable array,而不仅仅是一个可观察的。{3}}。 E.g:
this.name = ko.observableArray();
不
this.name = ko.observable('');
即使你稍后有self.name([])
,observable仍然只是一个observable(它的值是一个数组),而不是一个可观察的数组。
(我假设您在显示的代码之上某处var self = this;
。)
此外,由于它是一个名为 s 的数组,您可能需要将其称为names
而不是name
。
旁注:如果name
中的for (var x in name) {
是一个数组,那么你应该如何遍历数组。有关循环数组的各种正确方法,请参阅this question's answers。
附注2:HTML中的template
绑定似乎令人怀疑。您在那里提供HTML,而不是在单独的模板中。所以它应该是data-bind="foreach: name"
。
答案 1 :(得分:0)
我建议引入计算的observable(比如说self.filteredNames
),它依赖于self.names
数组(确实应该是ko.observableArray
)和当前值self.query
然后,您可以将模板绑定到self.filteredNames
而不是self.names
View Model定义的片段可能如下所示:
self = this;
/* ... any other code related to VM */
self.names = ko.observableArray([]); // it's supposed to be later filled with AJAX requests
// self.names = ko.observableArray(['foo', 'bar', 'baz']); // however you can try with this not to bother with actual data loading
self.query = ko.observable('');
self.filteredNames = ko.pureComputed(function(){
// value of this pureComputed observable would be automatically updated each time either self.query or self.names is updated
return self.names().filter(function(item) {
return item.toLowerCase().indexOf(self.query().toLowerCase()) >= 0;
});
});
/* ... any other code related to VM */
允许测试其工作原理的标记版本可能如下所示:
<input type="search" id="search-bar" placeholder="Enter a name" data-bind="value:query,valueUpdate: 'keyup'">
<ul id = "list" data-bind='foreach: filteredNames'>
<li data-bind=' text: $data'></li>
</div>