Автозаполнение Angularjs из $http

Я пытаюсь написать директиву автозаполнения, которая извлекает данные с сервера с помощью запроса $http (без использования каких-либо внешних плагинов или скриптов). В настоящее время он работает только со статическими данными. Теперь я знаю, что мне нужно вставить мой запрос $http в source: директивы, но я не могу найти никакой хорошей документации по этому вопросу.

HTTP-запрос

$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;   
            });

Директива

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

Вид

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

Итак, как мне правильно собрать все это вместе с помощью Angular?


person Gidon    schedule 27.08.2013    source источник
comment
Можете ли вы предоставить полный исходный код примера? Я просто хочу знать, в какое время вы на самом деле делаете HTTP-вызов. Заранее спасибо.   -  person Matthias    schedule 28.06.2015
comment
Вы нашли решение? я столкнулся с той же проблемой, кажется, что $scope.names пуст, когда директива загружается, вызов ajax остается позади   -  person Agung Setiawan    schedule 23.11.2015


Ответы (5)


Я сделал директиву автозаполнения и загрузил ее на GitHub. Он также должен иметь возможность обрабатывать данные из HTTP-запроса.

Вот демо: http://justgoscha.github.io/allmighty-autocomplete/ А вот документация и репозиторий: https://github.com/JustGoscha/allmighty-autocomplete

Таким образом, в основном вы должны вернуть promise, когда хотите получить данные из HTTP-запроса, который разрешается при загрузке данных. Поэтому вам нужно ввести $qservice/directive/controller, где вы отправляете свой HTTP-запрос.

Пример:

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

Надеюсь, это поможет.

person JustGoscha    schedule 19.12.2013
comment
Это вызывает у меня ошибку в html-файле шаблона, который вы включили в загрузку. Это требуется? Если это так, вы можете сделать это очевидным в документации. - person Metropolis; 11.06.2014
comment
Требует ли он, чтобы все данные были извлечены в память? Что делать, если у меня более 10 миллионов вариантов? :) - person tuxSlayer; 11.09.2014
comment
@tuxSlayer загрузите первые 20, которые соответствуют вашим критериям - person Artiom; 22.09.2014
comment
любой атрибут, чтобы ограничить количество результатов? - person Ashish Gupta; 30.10.2014
comment
Есть ли у этого тайм-аут, который вы можете установить, например... сделать http-запрос после того, как вы перестали печатать на 1 секунду? Я не хочу, чтобы он делал запрос при каждом нажатии клавиши... @JustGoscha - person dotnethaggis; 09.03.2015
comment
@JustGoscha, пожалуйста, помогите мне с этим вопросом: stackoverflow.com/questions/31578775/ - person Emil; 25.07.2015
comment
Я смог установить его. Но параметры выбора/результаты сопоставления отображаются за следующим элементом списка. Есть ли способ переместить их на передний план? Я ищу опыт, похожий на NGAutocomplete. - person techwestcoastsfosea; 08.12.2015
comment
@justgoscha, как лучше всего добавить к этому спиннер (анимацию загрузки)? - person gdubs; 10.06.2016

Используйте typehead angular-ui-bootstrap.

У него была отличная поддержка $http и promises. Кроме того, он вообще не включает JQuery, чистый AngularJS.

(Я всегда предпочитаю использовать существующие библиотеки, и если в них чего-то не хватает, чтобы открыть проблему или запрос на извлечение, гораздо лучше, чем снова создавать свою собственную)

person Urigo    schedule 07.10.2013
comment
Спасибо за ответ Уриго. Но, как я уже сказал в своем вопросе, я стараюсь избегать использования каких-либо внешних скриптов. Я ищу чисто угловое решение. Привет, Гидон - person Gidon; 22.10.2013
comment
имейте в виду, что на сегодняшний день Typeahead в angular-ui-bootstrap несовместим с Angular 1.3. - person Rocco; 28.09.2014
comment
Спасибо, @Rocco, ты избавил меня от многих головных болей! - person Chris; 04.12.2014
comment
Как получить id при выборе. - person user254153; 23.11.2016

Вам нужно написать контроллер с функцией ng-change в области видимости. В обратном вызове ng-change вы выполняете вызов сервера и обновляете завершения. Вот заготовка (без $http, так как это планк):

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);
    }
  }
}
person madhead    schedule 27.08.2013
comment
Спасибо за ответ сумасшедший. Но, как я уже сказал в своем вопросе, я стараюсь избегать использования каких-либо внешних скриптов. В своем ответе вы используете скрипт начальной загрузки angular-ui. Я ищу чисто угловое решение. Привет, Гидон - person Gidon; 28.08.2013
comment
Я использую angular-ui для директивы typeahead (само автозаполнение). - person madhead; 28.08.2013

самый простой способ сделать это в angular или angularjs без внешних модулей или директив — использовать список и список данных HTML5. Вы просто получаете json и используете ng-repeat для подачи параметров в список данных. JSON вы можете получить из ajax.

в этом примере:

  • ctrl.query — это запрос, который вы вводите при вводе.
  • ctrl.msg — это сообщение, которое отображается в заполнителе
  • ctrl.dataList — это полученный json

затем вы можете добавить фильтры и порядок в ng-reapet

<сильный>!! Идентификатор списка и списка данных должен иметь одно и то же имя!!

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

ОБНОВЛЕНИЕ: это собственный HTML5, но будьте осторожны с типом браузера и версии. проверьте это: https://caniuse.com/#search=datalist.

person londox    schedule 10.07.2017

Я нашел эту ссылку полезной

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