【问题标题】:KnockoutJs filter empties the list after searchKnockoutJs 过滤器在搜索后清空列表
【发布时间】:2018-05-08 10:40:30
【问题描述】:

我正在使用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 检索数据(二维列表)然后进行解析,然后我将解析数据的每个第一个条目 (arsed_data[i][0]) 分配为名称 observable,如代码。

该列表旨在根据搜索框条目过滤内容,它最初显示所有名称,但是一旦我在搜索框中输入内容,名称列表就会变为空,可能是什么原因,是否存在有办法解决吗?

【问题讨论】:

  • self 是什么?您是否在未显示的代码中设置了var self = this;

标签: javascript jquery ajax knockout.js


【解决方案1】:

如果你想直接在 observable 上使用像 push 这样的数组方法,你需要把它变成一个 observable array,而不仅仅是一个 observable。例如:

this.name = ko.observableArray();

不是

this.name = ko.observable('');

即使你后来有self.name([]),observable 仍然只是一个 observable(其值是一个数组),而不是一个 observable 数组。

(我假设您在显示的代码上方的某处有 var self = this;。)

此外,由于它是一个名称数组s,您可能希望将其称为names 而不是name


旁注:如果for (var x in name) { 中的name 是一个数组,那么您不应该这样循环数组。有关循环数组的各种正确方法,请参阅this question's answers


旁注 2:您的 HTML 中的 template 绑定似乎很可疑。您正在那里提供 HTML,而不是在单独的模板中。所以应该是data-bind="foreach: name"

【讨论】:

    【解决方案2】:

    我建议引入既依赖于self.names 数组(实际上应该是ko.observableArray)和self.query 的当前值的计算的observable(比如self.filteredNames) 然后,您可以将模板绑定到 self.filteredNames 而不是 self.names 视图模型定义的片段可能如下所示:

    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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 2015-12-19
      相关资源
      最近更新 更多