#javascript #angularjs #filter #angularjs-ng-repeat
#javascript #angularjs #Фильтр #angularjs-ng-repeat
Вопрос:
Я хочу создать заголовок типа в AngularJS, и, следуя этому руководству, я проделал большую часть пути. Единственное, чего он не делает для меня, это то, что я хочу, чтобы весь список отображался при первом щелчке в поле, вместо того, чтобы ожидать, пока ввод что-нибудь покажет.
В шаблоне он имеет
<input type="text" ng-model="model" placeholder="{{prompt}}"
ng-keydown="selected=false"/>
...
<div class="item" ng-repeat="item in items | filter:model track by $index"
ng-click="handleSelection(item[title])" style="cursor:pointer"
ng-class="{active:isCurrent($index)}" ng-mouseenter="setCurrent($index)">
Мне нужно создать пользовательский фильтр, который, я полагаю, был бы похож на
.filter('psudoFilter', function($filter){
var original_filter = $filter('filter');
return function(input){
if(input.length === 0){
return // What should I return if I don't want to change the data?
} else {
return original_filter(input_to_filter_items_by); //Filter as usual
}
}
});
Проблема, с которой я сталкиваюсь, заключается в том, что должна возвращать внутренняя функция, чтобы она не фильтровала при отсутствии ввода? как фильтр взаимодействует с данными, которые он фактически будет фильтровать?
Ответ №1:
Проблема на самом деле не в фильтре. Проблема в том, что список элементов виден только в том случае, если что-то введено в текстовое поле:
<div class="items" ng-hide="!model.length || selected">
Что вы хотите сделать, это показать список при нажатии на текстовое поле. Я предполагаю, что вы также хотите скрыть список, когда текстовое поле теряет фокус. Добавьте ng-focus
и ng-blur
события в текстовое поле. Я устанавливаю boxHasFocus
свойство в этих событиях и изменяю ng-hide
в списке, чтобы оно отображало, когда boxHasFocus
оно истинно.
<input type="text" ng-model="model" placeholder="{{prompt}}" ng-keydown="selected=false" ng-focus="boxHasFocus=true" ng-blur="boxHasFocus=false" />
<br/>
<div class="items" ng-hide="(!model.length || selected) amp;amp; !boxHasFocus">
Однако с этим есть проблема. Изначально элементы списка выглядели так:
<div class="item" ng-repeat="item in items | filter:model track by $index" ng-click="handleSelection(item[title])" ...
Проблема в том, что blur
событие срабатывает перед click
событием, поэтому список исчезает до того, как он сможет зарегистрировать, что вы нажали на элемент. Решение состоит в том, чтобы использовать ng-mousedown
вместо ng-click
, потому mousedown
что события запускаются перед blur
событиями.
<div class="item" ng-repeat="item in items | filter:model track by $index" ng-mousedown="handleSelection(item[title])"
Вот демонстрация, показывающая, как это работает.
Комментарии:
1. Спасибо за хорошо объясненный ответ. Просто из любопытства, где вы нашли порядок событий наведения курсора мыши, затем размытия, а затем щелчка?
2. Я просто погуглил. На самом деле нет окончательной спецификации относительно порядка событий; каждый браузер может реализовать его по-разному (к сожалению).
Ответ №2:
Проверьте это. Единственная часть, которую этот пример не обрабатывает, — это отображение всего списка, когда пользователь нажимает на него для начала. Но это будет легко подключить.
http://www.byteblocks.com/Post/Autosuggest-text-box-using-AngularJS