KnockoutJs过滤器在搜索后清空列表

时间:2017-11-24 11:59:12

标签: javascript jquery ajax knockout.js

我正在使用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码。

该列表意味着根据搜索框条目过滤内容,并且它最初显示所有名称,但是只要我在搜索框中键入内容,名称列表就会变空,可能的原因是什么?一种解决方法吗?

2 个答案:

答案 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>