AngularJs UI typeahead соответствует ведущим персонажам
Функциональность typeahead в пользовательском интерфейсе AngularJs кажется простой и мощной, однако я пытался выяснить, как добиться соответствия для ведущих персонажей. Например, если я ввожу "A" в поле ввода, я бы хотел видеть все состояния, начинающиеся с "A" , а не все состояния, содержащие "A" в имени. Я искал пару дней на этом и кажется, что Angular имеет концепцию настраиваемого фильтра, который имеет "компаратор". Документы на этом имеют простой пример, который не показывает точный синтаксис для реализации компаратора.
html выглядит так:
<div>Selected: <span>{{selected}}</span></div>
<div><input type="text" ng-model="selected" typeahead="name for name in states | filter:selected"></div>
Основной javascript выглядит следующим образом
angular.module('firstChar', ['ui.bootstrap']);
function TypeaheadCtrl($scope) {
$scope.selected = undefined;
$scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
}
У меня есть плункер здесь http://plnkr.co/edit/LT6pAnS8asnpFEd5e6Ri
Таким образом, задача в двух словах состоит в том, чтобы заставить тип AngularUI соответствовать только ведущим символам.
Любая помощь или идеи по этому поводу были бы чрезвычайно оценены.
Ответы
Ответ 1
В конце дня ваш вопрос не очень специфичен для директивы typeahead
, но он больше связан с тем, как работают фильтры AngularJS.
Перед представлением рабочего решения обратите внимание, что директива typeahead
использует интенсивную инфраструктуру AngularJS ($ http, promises) и язык выражения. Поэтому важно понять, что states | filter:selected
не более чем выражение AngularJS.
Взглянув на вышеприведенное выражение, нам нужно найти способ фильтрации массива для возврата списка совпадающих элементов. Единственная особенность директивы typeahead заключается в том, что существует переменная $viewValue
, представляющая значение, введенное пользователем в поле ввода. Поэтому нам просто нужно отфильтровать массив states
для возврата элементов, начинающихся с $viewValue
.
Существует много способов сделать это, но поскольку вы упоминали о компараторе для фильтров (обратите внимание, что они были введены только в версии 1.1.x AngularJS), вам нужно будет определить функцию компаратора, которая должна решить, если данный элемент должен быть возвращен в списке результатов или нет. Такая функция может выглядеть следующим образом:
$scope.startsWith = function(state, viewValue) {
return state.substr(0, viewValue.length).toLowerCase() == viewValue.toLowerCase();
}
Определив, что использование очень просто:
typeahead="name for name in states | filter:$viewValue:startsWith"
Вот рабочий план: http://plnkr.co/edit/WWWEwU4oPxvbN84fmAl0?p=preview
Ответ 2
Пользовательский фильтр для получения соответствия, которое должно выполняться над ведущими символами в окне автозапуска типа headhead.
(function() {
// Create global filters using angular.filter() only. Never use local filters inside
// controllers/services. This enhances testing and reusability.
function xpTypeaheadFilter() {
return function(items, props) {
var out = [];
if (angular.isArray(items)) {
items.forEach(function(item) {
var text = props.toLowerCase();
var itemLoverCase =item.toLowerCase();
var substr = itemLoverCase.substr(0, text.length);
if (substr === text ) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
console.log("out lem", out.length);
return out;
};
}
// Pass functions into module methods rather than assigning a callback.
// This helps aid with readability and helps reduced the amount of code "wrapped"
// inside Angular.
angular.module('common')
.filter('xpTypeaheadFilter', xpTypeaheadFilter);
})();
<input type="text" ng-model="vesselName" placeholder="Vessel Name" typeahead="vesselName for vesselName in vesselNames | xpTypeaheadFilter:$viewValue | limitTo:8" class="form-control form-textbox" >
Ответ 3
Я только что отредактировал пост, помеченный как ответ, и он работает, когда в списке есть Id и заголовок:
<input type="text" ng-model="ledgerstatementModel.Supplier" typeahead="supplier as supplier.Name for supplier in supplierList | filter:{Name:$viewValue}:startsWith" class="form-control">
и в js:
$scope.startsWith = function (supplier, viewValue) {
return supplier.substr(0, viewValue.length).toLowerCase() == viewValue.toLowerCase();
}