AngularJs UI预先匹配前导字符

时间:2013-08-25 14:22:12

标签: javascript angularjs filter angular-ui typeahead

AngularJs UI中的预先输入功能看起来简单而强大,但我一直试图弄清楚如何在主要角色上进行匹配。例如,如果我在输入框中键入“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预先输入只匹配主要字符。

对此的任何帮助或想法都将非常感激。

3 个答案:

答案 0 :(得分:53)

在一天结束时,您的问题并非真正针对typeahead指令,而是与AngularJS过滤器的工作方式有关。

在提出工作解决方案之前,请注意typeahead指令大量使用AngularJS基础结构($ http,promises)和表达式语言。因此,重要的是要认识到states | filter:selected只不过是一个AngularJS表达式。

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

有很多方法可以做到这一点但是因为你已经提到过滤器的比较器(请注意那些只是在1.1.x版本的AngularJS中引入)你必须定义一个比较器函数来决定是否给定item应该在结果列表中返回。这样的功能可能如下所示:

$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

答案 1 :(得分:1)

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

&#13;
&#13;
(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);
})();
&#13;
<input type="text" ng-model="vesselName" placeholder="Vessel Name" typeahead="vesselName for vesselName in vesselNames | xpTypeaheadFilter:$viewValue | limitTo:8"  class="form-control form-textbox" >
&#13;
&#13;
&#13;

答案 2 :(得分: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();
    }