2015-04-16 3 views
2

Я пытаюсь выполнить поиск по имени в наблюдаемом массиве. Вот мой код:Поиск нокаута в наблюдаемом массиве

<input class="form-control" data-bind="value: Query, valueUpdate: 'keyup'" autocomplete="off"> 

И мой код в ViewModel

viewModel.Query = ko.observable(''); 

viewModel.search = function(value) { 
    viewModel.TestList.removeAll(); 
    for (var x in viewModel.TestList) { 
     if (viewModel.TestList[x].Name.toLowerCase().indexOf(value.toLowerCase()) >= 0) { 
      viewModel.TestList.push(viewModel.TestList[x]); 
     } 
    } 
} 
viewModel.Query.subscribe(viewModel.search); 

Во-первых: Я хотел бы искать по имени строки. Два: Есть ли какие-либо другие решения, чтобы не удалить все элементы из представления? Я имею в виду, что когда строка запроса пуста, должен быть весь список еще раз.

Теперь у меня есть сообщение об ошибке:

TypeError: viewModel.TestList[x].Name is undefined 
+0

вам нужно 'if (value) removeAll()' guard – dandavis

+0

, это должно работать, попробуйте этот 'viewModel.TestList() [x] .Name' –

+0

попробуйте это, что прекрасно работает http://jsfiddle.net/LkqTU/ 23731 /. cheers –

ответ

7

Используйте вычисленный наблюдаемый массив, чтобы показать результаты поиска, вдоль этих линий:

var viewModel = { 
 
    items: [ { Name: "Apple part" }, { Name: "Apple sauce" }, { Name: "Apple juice" }, { Name: "Pear juice" }, { Name: "Pear mush" }, { Name: "Something different" } ] 
 
}; 
 

 
viewModel.Query = ko.observable(''); 
 

 
viewModel.searchResults = ko.computed(function() { 
 
    var q = viewModel.Query(); 
 
    return viewModel.items.filter(function(i) { 
 
     return i.Name.toLowerCase().indexOf(q) >= 0; 
 
    }); 
 
}); 
 

 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<input class="form-control" data-bind="value: Query, valueUpdate: 'keyup'" autocomplete="off"> 
 

 
<h3>Search results:</h3> 
 
<ul data-bind="foreach: searchResults"> 
 
    <li data-bind="text: Name"></li> 
 
</ul> 
 

 
<h3>All items:</h3> 
 
<ul data-bind="foreach: items"> 
 
    <li data-bind="text: Name"></li> 
 
</ul>

Это также устраняет необходимость подписку или отдельную функцию.

Этот пример использует:

  • A regular observableArrayдля хранения всехitems (этот список всегда одинаково, независимо от поискового запроса);
  • A read-only computed observable, который возвращает отфильтрованный массив элементов, соответствующих вашему запросу;
  • The array filter method (вы называете это на observableArray, но KO просто перенаправляет его в базовый массив);

Как вы можете видеть в примере, items всегда будут содержать все объекты, а searchResults просто посмотреть фильтрованное только для чтения на этом массиве.

+0

, так что значит, в моем HTML мне нужно скрыть и показать массив поискаРезультаты и элементы? –

Смежные вопросы