淘汰赛js表过滤在新版本上打破

时间:2014-06-23 10:28:28

标签: javascript knockout.js

我正在尝试在此演示中实现该功能: http://opensoul.org/2011/06/23/live-search-with-knockoutjs/

我设法让一切正常,但演示使用了一个非常旧版的淘汰赛。 当我升级淘汰版时,功能会中断。

这是我更新的代码:

$(function() {
  var assets = [
    {id: "1", poster: "Pic010.jpg", name: "Mike", category: "category1", type: "Movie", popup: "1" },
    {id: "2", poster: "Pic06.jpg", name: "James", category: "category2", type: "Movie", popup: "2" },
    {id: "3", poster: "Pic04.jpg", name: "John", category: "category1", type: "Pop-up", popup: "3" },
    {id: "4", poster: "Pic07.jpg", name: "Bob", category: "category2", type: "Pop-up", popup: "4" },
    {id: "5", poster: "Pic011.jpg", name: "Mary", category: "category3", type: "Promo", popup: "5" }
  ];

  var viewModel = {
    assets: ko.observableArray(assets),

    query: ko.observable(''),

    search: function(value) {
      viewModel.assets.removeAll();
      for(var x in assets) {
        if(assets[x].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
          viewModel.assets.push(assets[x]);
        }
      }
    }
  };

  viewModel.query.subscribe(viewModel.search);

  ko.applyBindings(viewModel);
});

显示:

    <form action="#">
      <input class="form-control" placeholder="Search…" type="search" name="q" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off">
    </form>

  <div class="content">
    <table>
      <tbody data-bind="foreach:assets">
        <tr>
    <td style="vertical-align: middle" data-bind="text: id">&nbsp;</td>
    <td><img data-bind="attr:{ src: '/manager/files/' + poster }" height="100px" /></td>
    <td style="vertical-align: middle" data-bind="text: name"></td>
    <td style="vertical-align: middle" data-bind="text: category"></td>
    <td style="vertical-align: middle" data-bind="text: type"></td>
    <td style="vertical-align: middle" data-bind="text: popup"></td>
    <td class="actions" style="vertical-align: middle">
        <a href="/Assets/edit/5" data-bind="attr:{ href: '/Assets/edit/' + id }"><i class="fa fa-pencil-square-o"></i></a>
        <form data-bind="attr:{ action: '/Assets/delete/' + id, name: 'delete_' + id, id: 'delete_'+ id }" style="display:none;" method="post"><input type="hidden" name="_method" value="POST"></form>
        <a href="#" ><i class="fa fa-trash-o"></i></a>
    </td>
</tr>
    </tbody>
        </table>
  </div>

以下是使用Knockout版本1.21的示例:http://jsfiddle.net/7ZLdk/1/示例不适用于3.0版:http://jsfiddle.net/7ZLdk/2/

1 个答案:

答案 0 :(得分:3)

此行为已于2011年更改:Updated remove and removeAll to modify their underlying arrays rather han creating new arrays

现在,当您在removeAll上调用ko.observableArray时,它会删除基础数组中的项目,因此在您的情况下,它会清空原始的assets数组。

快速解决方法是在分配到ko.observableArray时克隆数组:

assets: ko.observableArray(assets.slice(0)),

演示JSFiddle

更好,更现代的解决方案是使用ko.computed propertyarrayFilter helper method进行过滤:

 assets: ko.computed(function () {
     if (!viewModel.query())
         return assets;
     return ko.utils.arrayFilter(assets, function(item) {
        return item.name.toLowerCase().indexOf(viewModel.query().toLowerCase()) >= 0;             
     });
 }, null, {deferEvaluation: true})

演示JSFiddle