Angularjs autocompletare din $http (Programare, Angularjs, Autocompletare, Directivă, Angular Http)

Gidon a intrebat.

Încerc să scriu o directivă de autocompletare care preia date de pe server folosind o cerere $http (fără a utiliza plugin-uri sau script-uri externe). În prezent funcționează doar cu date statice. Acum, știu că trebuie să inserez cererea $http în source: a directivei, dar nu pot găsi nicio documentație bună pe această temă.

http request

$http.post($scope.url, { "command": "list category() names"}). 
            success(function(data, status) {
                $scope.status = status;
                $scope.names = data;    
            })
            .
            error(function(data, status) {
                $scope.data = data || "Request failed";
                $scope.status = status;   
            });

Directiva

app.directive('autoComplete', function($timeout) {
    return function(scope, iElement, iAttrs) {
            iElement.autocomplete({
                source: scope[iAttrs.uiItems],
                select: function() {
                    $timeout(function() {
                      iElement.trigger('input');
                    }, 0);
                }
            });
        };
    });

Vezi

<input auto-complete ui-items="names" ng-init="manualcat='no category entered'" ng-model="manualcat"> 

Așadar, cum pun toate acestea cap la cap în mod corect în modul Angular?

Comentarii

  • Puteți furniza codul sursă complet al exemplului? Vreau doar să știu în ce moment se face de fapt apelul HTTP. Mulțumesc în avans. –  > Por Matthias.
  • ați găsit soluția? mă confrunt cu aceeași problemă, se pare că $scope.names este gol când se încarcă directiva, apelul ajax este lăsat în urmă –  > Por Agung Setiawan.
5 răspunsuri
JustGoscha

Am făcut o directivă de autocompletare și am încărcat-o pe GitHub. De asemenea, ar trebui să fie capabil să gestioneze datele dintr-un HTTP-Request.

Iată demo-ul: http://justgoscha.github.io/allmighty-autocomplete/Și aici documentația și depozitul: https://github.com/JustGoscha/allmighty-autocomplete

Deci, în principiu, trebuie să returnați un promise atunci când doriți să obțineți date dintr-o cerere HTTP, care se rezolvă atunci când datele sunt încărcate. Prin urmare, trebuie să injectați $qserviciul/directiva/controlerul în care emiteți cererea HTTP.

Exemplu:

function getMyHttpData(){
  var deferred = $q.defer();
  $http.jsonp(request).success(function(data){
    // the promise gets resolved with the data from HTTP
    deferred.resolve(data);
  });
  // return the promise
  return deferred.promise;
}

Sper că acest lucru vă ajută.

Comentarii

  • Acest lucru îmi aruncă o eroare în fișierul html al șablonului pe care l-ați inclus în descărcare. Este acesta necesar? Dacă da, poate doriți să faceți acest lucru evident în documentație –  > Por Metropolis.
  • Este necesar ca toate datele să fie preluate în memorie? Ce se întâmplă dacă am peste 10 milioane de variante? 🙂 –  > Por tuxSlayer.
  • @tuxSlayer descarcă primele 20 care corespund criteriilor tale –  > Por Artiom.
  • vreun atribut pentru a limita numărul de rezultate? –  > Por Ashish Gupta.
  • Are acest lucru un timeout pe care îl puteți seta, de exemplu… face o cerere http după ce nu mai tastați timp de 1 secundă? Nu vreau să facă o cerere la fiecare tastă apăsată… @JustGoscha –  > Por dotnethaggis.
Urigo

Utilizați angular-ui-bootstrap’s typehead.

A avut un suport excelent pentru $http și promisiuni. de asemenea, nu include deloc JQuery, AngularJS pur.

(Întotdeauna prefer să folosesc bibliotecile existente și dacă le lipsește ceva să deschid o problemă sau o cerere de tragere, mult mai bine decât să vă creați din nou propria bibliotecă)

Comentarii

  • Mulțumesc pentru răspuns, Urigo. Dar, așa cum am spus în întrebarea mea, încerc să evit utilizarea oricăror scripturi externe. Caut o soluție pur angular. Noroc, Gidon –  > Por Gidon.
  • țineți cont de faptul că, începând de astăzi, Typeahead din angular-ui-bootstrap nu este compatibil cu Angular 1.3 –  > Por Rocco.
  • Mulțumesc @Rocco m-ai salvat de multe bătăi de cap! –  > Por Chris.
  • Cum să obțineți id pe select. –  > Por user254153.
madhead

Trebuie să scrieți un controler cu ng-change funcție în domeniu. În ng-change callback faceți un apel la server și actualizați completările. Iată un stub (fără $http deoarece acesta este un plunk):

HTML

<!doctype html>
<html ng-app="plunker">
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
        <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
        <script src="example.js"></script>
        <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
    </head>
    <body>
        <div class='container-fluid' ng-controller="TypeaheadCtrl">
            <pre>Model: {{selected| json}}</pre>
            <pre>{{states}}</pre>
            <input type="text" ng-change="onedit()" ng-model="selected" typeahead="state for state in states | filter:$viewValue">
        </div>
    </body>
</html>

JS

angular.module('plunker', ['ui.bootstrap']);

function TypeaheadCtrl($scope) {
  $scope.selected = undefined;
  $scope.states = [];

  $scope.onedit = function(){
    $scope.states = [];

    for(var i = 0; i < Math.floor((Math.random()*10)+1); i++){
      var value = "";

      for(var j = 0; j < i; j++){
        value += j;
      }
      $scope.states.push(value);
    }
  }
}

Comentarii

  • Mulțumesc pentru răspuns madhead. Dar, așa cum am spus în întrebarea mea, încerc să evit să folosesc scripturi externe. În răspunsul tău folosești scriptul angular-ui bootstrap. Eu caut o soluție pur angular. Noroc, Gidon –  > Por Gidon.
  • Folosesc angular-ui pentru typeahead directivă (autocompletare în sine). –  > Por madhead.
londox

cel mai simplu mod de a face acest lucru în angular sau angularjs fără module sau directive externe este să folosești list și datalist HTML5. Trebuie doar să obțineți un json și să folosiți ng-repeat pentru alimentarea opțiunilor în datalist. Json-ul îl puteți prelua din ajax.

în acest exemplu:

  • ctrl.query este interogarea pe care o introduceți atunci când tastați.
  • ctrl.msg este mesajul care se afișează în spațiul rezervat.
  • ctrl.dataList este json-ul preluat.

apoi puteți adăuga filtre și orderby în ng-reapet

!!! list și id-ul datalist trebuie să aibă același nume !!!

 <input type="text" list="autocompleList" ng-model="ctrl.query" placeholder={{ctrl.msg}}>
<datalist id="autocompleList">
        <option ng-repeat="Ids in ctrl.dataList value={{Ids}}  >
</datalist>

UPDATE : este nativ HTML5 dar fiți atenți la tipul de browser și versiunea. verificați : https://caniuse.com/#search=datalist.

Joe B

Am găsit acest link util

$scope.loadSkillTags = function (query) {
var data = {qData: query};
   return SkillService.querySkills(data).then(function(response) {
   return response.data;
  });
 };