web-dev-qa-db-de.com

AngularJs UI-Typenkopfübereinstimmung mit führenden Zeichen

Die Typeahead-Funktionalität in der AngularJs-Benutzeroberfläche scheint einfach und mächtig zu sein. Allerdings habe ich versucht herauszufinden, wie man die Übereinstimmung mit den führenden Zeichen erzielen kann. Wenn ich beispielsweise 'A' in das Eingabefeld eingebe, würde ich gerne alle Zustände sehen, die mit 'A' beginnen, und nicht alle Zustände, die ein 'A' im Namen enthalten. Ich habe ein paar Tage gesucht zu diesem Thema scheint es, dass Angular das Konzept eines benutzerdefinierten Filters mit einem 'Komparator' hat. Die Dokumente hierzu haben ein einfaches Beispiel, das nicht die genaue Syntax für die Implementierung eines Komparators zeigt. 

Die HTML-Datei sieht folgendermaßen aus:

<div>Selected: <span>{{selected}}</span></div>
    <div><input type="text" ng-model="selected" typeahead="name for name in states | filter:selected"></div>

Das grundlegende Javascript sieht so aus

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'];
    }

Ich habe hier einen Plunker http://plnkr.co/edit/LT6pAnS8asnpFEd5e6Ri

Die Herausforderung in einer Nussschale besteht also darin, den AngularUI-Typkopf nur auf die führenden Zeichen abzustimmen.

Jede Hilfe oder Anregung dazu wäre sehr dankbar.

21
pat capozzi

Am Ende des Tages ist Ihre Frage nicht wirklich spezifisch für die typeahead-Direktive, sondern hat mehr mit der Funktionsweise von AngularJS-Filtern zu tun.

Bevor Sie eine funktionierende Lösung präsentieren, beachten Sie, dass die typeahead-Direktive die AngularJS-Infrastruktur ($ http, verspricht) und die Ausdruckssprache stark ausnutzt. Daher ist es wichtig zu wissen, dass der states | filter:selected nichts weiter als ein AngularJS-Ausdruck ist.

Wenn Sie den obigen Ausdruck betrachten, müssen wir einen Weg finden, ein Array filtern, um eine Liste der übereinstimmenden Elemente anzuzeigen. Das einzige Besondere an der Direktive typeahead ist, dass es eine $viewValue-Variable gibt, die einen von einem Benutzer in das Eingabefeld eingegebenen Wert darstellt. Daher müssen wir im Wesentlichen nur das states-Array filtern, um Elemente zurückzugeben, die mit dem $viewValue beginnen.

Es gibt viele Möglichkeiten, dies zu tun. Da Sie jedoch den Komparator für Filter erwähnt haben (bitte beachten Sie, dass diese nur in der Version 1.1.x von AngularJS eingeführt wurden), müssen Sie eine Komparatorfunktion definieren, die entscheidet, ob ein bestimmtes Element verwendet werden soll zurückgegeben in der Ergebnisliste oder nicht. Eine solche Funktion könnte wie folgt aussehen:

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

Nachdem die Verwendung definiert wurde, ist sie sehr einfach:

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

Hier ist der funktionierende Plunk: http://plnkr.co/edit/WWWEwU4oPxvbN84fmAl0?p=preview

53

Benutzerdefinierter Filter für den Abgleich der führenden Zeichen in der Typeahead-Autovervollständigungsbox.

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

1
Rejayi CS

Ich habe gerade einen Beitrag bearbeitet, der als beantwortet markiert wurde. Er funktioniert, wenn die Liste sowohl die ID als auch den Titel enthält:

<input type="text" ng-model="ledgerstatementModel.Supplier" typeahead="supplier as supplier.Name for supplier in supplierList | filter:{Name:$viewValue}:startsWith" class="form-control">

und in js:

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