22

AngularJs UI 中的 typeahead 功能看起来简单而强大,但是我一直在试图弄清楚如何在前导字符上完成匹配。例如,如果我在输入框中键入“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'];
    }

我在这里有一个 plunker http://plnkr.co/edit/LT6pAnS8asnpFEd5e6Ri

因此,简而言之,挑战是让 AngularUI 预先输入以匹配前导字符。

对此的任何帮助或想法将不胜感激。

4

3 回答 3

54

归根结底,您的问题并不是特定于typeahead指令,而是更多地与 AngularJS 过滤器的工作方式有关。

在提出一个可行的解决方案之前,请注意该typeahead指令大量使用了 AngularJS 基础设施($http、promises)和表达式语言。因此,重要的是要意识到states | filter:selectedAngularJS 表达式只不过是一个表达式。

看看上面的表达式,我们需要找到一种过滤数组以返回匹配项列表的方法。typeahead 指令唯一的特殊之处是有一个$viewValue变量表示用户在输入框中输入的值。所以我们基本上只需要过滤states数组以返回以$viewValue.

有很多方法可以做到这一点,但是由于您提到了过滤器的比较器(请注意,这些仅在 AngularJS 的 1.1.x 版本中引入),您必须定义一个比较器函数,该函数应该决定给定项目是否应该是在结果列表中返回与否。这样的函数可能如下所示:

$scope.startsWith = function(state, viewValue) {
  return state.substr(0, viewValue.length).toLowerCase() == viewValue.toLowerCase();
} 

定义了它的用法非常简单:

typeahead="name for name in states | filter:$viewValue:startsWith"

这里是工作 plunk:http ://plnkr.co/edit/WWWEwU4oPxvbN84fmAl0?p=preview

于 2013-08-25T17:20:10.553 回答
1

自定义过滤器,用于在打字头自动完成框中的前导字符上进行匹配。

(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" >

于 2015-06-11T08:49:38.237 回答
0

我刚刚编辑了标记为已回答的帖子,当列表同时具有 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();
    }
于 2017-05-24T07:53:05.700 回答