Angular bootstrap typehead с асинхронной загрузкой на один символ позади

Я реализовал следующий код ввода в директиве.

Вот HTML:

<div>
    <input type="text"
           ng-model="company"
           uib-typeahead="company as company.name for company in companyByName($viewValue)"
           typeahead-loading="loadingCompanies"
           typeahead-no-results="noCompanyResults"
           class="form-control">
    <i ng-show="loadingCompanies" class="glyphicon glyphicon-refresh"></i>
    <div ng-show="noCompanyResults">
        <i class="glyphicon glyphicon-remove"></i> No Results Found
    </div>
</div>

Вот JavaScript:

  scope.companyByName = function() {
    var companyName = scope.company.name ? scope.company.name : scope.company;
    var searchTerms = {name: companyName, startRow: 0, endRow: 20};

    return $http.post("backend/get/companies.php", searchTerms).then((result) => {
      $log.info("Companies", result.data.results);
      return result.data.results;
    });
  };

PHP-код backend/get/companies.php принимает строку поиска и возвращает массив объектов с атрибутами id и name с именами, содержащими эту строку поиска.

Вот поведение, которое я испытываю:

Когда я ввожу один символ «f» в поле typeahead, значение companyName, передаваемое внутреннему сценарию, равно «» (пустая строка). backend/get/companies.php возвращает все результаты.

Когда я набираю второй символ «fo» в поле ввода, значение companyName, передаваемое во внутренний скрипт, равно «f». backend/get/companies.php возвращает результаты, соответствующие "f".

Ввод третьего символа «foo» возвращает результаты, соответствующие «fo» и т. д.

Я смоделировал свой код по официальным примерам. Что здесь происходит? Я чувствую, что каким-то образом функция companyByName() вызывается событием, которое срабатывает до того, как символ будет введен во входные данные. Есть предположения?


person jkndrkn    schedule 16.11.2015    source источник
comment
используйте $viewValue для поиска   -  person harishr    schedule 27.11.2015


Ответы (2)


Проблема в том, что ng-модель отстает от значений просмотра. Когда companyByName вызывается, ng-модель не обновляется до последнего значения из поля ввода. Чтобы получить последнее значение из ввода, вы должны использовать аргумент, который передается в функцию companyByName:

scope.companyByName = function(viewValue) {
  var searchTerms = {name: viewValue, startRow: 0, endRow: 20};

  return $http.post("backend/get/companies.php", searchTerms).then((result) => {
    $log.info("Companies", result.data.results);
    return result.data.results;
  });
};
person Stubb0rn    schedule 23.11.2015

Typeahead должен быть быстрее, чем дайджест страницы, и поэтому использование области видимости вместо значения просто не совсем подходит.

Вот плункер, показывающий обе версии. По сути, вам нужна первая версия, как показано ниже.

 scope.companyByName = function(val) {
    var companyName = val;
    var searchTerms = {name: companyName, startRow: 0, endRow: 20};

    return $http.post("backend/get/companies.php", searchTerms).then((result) => {
      $log.info("Companies", result.data.results);
      return result.data.results;
    });
  };
person Lee.Winter    schedule 27.11.2015