当用户键入速度非常快时,Typeahead 不起作用

Typeahead is not working when user types very fast

我正在使用 typeahead,在搜索框中键入其显示的建议,而建议是从服务器获取的。

除非用户输入速度非常快,否则它工作正常。例如,如果我们输入 storm 它会显示记录。当快速输入同一个词时,当我在 response 中获取数据时,它没有显示建议。我已经通过在框上方打印 JSON 进行检查,所以当我快速编写 storm 时它显示 JSON 但没有显示以下建议。

这是html

<input type="text" ng-model="header.search"
    typeahead-on-select="searchClicked($item)"
    uib-typeahead="state as state.data.name for state in suggestions | filter:$viewValue | limitTo:8"
    typeahead-min-length="0" placeholder="Søg..." search-products>

search-products 是用于广播搜索值的指令。这是指令代码。

APP.directive('searchProducts', searchProducts);
function searchProducts($state) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch(attrs.ngModel, function(searchVal) {
                scope.$broadcast('searchTheProducts', searchVal);
            });
        }
    };
}

这是我们获取数据的服务调用。

$scope.$on('searchTheProducts', function(event, query) {
    if (query) {
        headerService.getSearchSuggestions(query).then(
            function(response) {
                $scope.suggestions = response;
            },
            function(err) {
                console.log('Error: ' + err);
            }
        );
    }
});

这里是服务逻辑

  function getSearchSuggestions(query) {
    pendingRequests.cancelAll();
    var url = ApiBaseUrl + "/search/suggestions?query=" + query;
    var deferred = $q.defer();
    pendingRequests.add({
        url: url,
        canceller: deferred
    });

    pending = true;
    $http({
        method: "GET",
        url: url,
        timeout: deferred.promise
    }).then(
        function(successData) {

            deferred.resolve(successData.data.data);
        },
        function(err) {

            deferred.reject(err);
        }
    );
    return deferred.promise;
}

我不太清楚你为什么有:

angular.forEach(response, function(val, key) {
  $scope.suggestions= response;
});

如果 response 是 100 个项目,那么出于某种原因您每次都在更新 $scope.suggestions,这 可能 导致了问题。只需删除 angular.forEach 并只使用 $scope.suggestions = response 即可。

您可以使用 typeahead-wait-ms 属性,这样您就不会在每次 ketstroke 时查询:

<input typeahead-wait-ms="50">

我认为您不需要自定义指令来触发 $http 调用以在您的输入值 changes.Instead 时获取结果,您可以执行以下操作

<input type="text" ng-model="header.search"
    typeahead-on-select="searchClicked($item)"
    uib-typeahead="state as state.data.name for state in suggestions($viewValue) | filter:$viewValue | limitTo:8"
    typeahead-min-length="0" placeholder="Søg..." >

在您的 JS 控制器中,您可以编写函数 $scope.suggestions() 来获取查询类型的新结果。

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

    app.factory('dataProviderService', ['$http', function($http) {
        var factory = {};
        factory.getCities = function(input) {
            //I've used google api to fetch cities ..we can place our service call here..
          return  $http.get('//maps.googleapis.com/maps/api/geocode/json', {
                params: {
                    address: input,
                    sensor: false
                }
            }).then(function(response) {//on success the results can be further processed as required..
                return response.data.results.map(function(item) {
                    return item.formatted_address;
                });
            });

        };

        return factory;
    }]);

     app.controller('TypeaheadCtrl', ['$scope', '$log','$http', 'dataProviderService', function($scope, $log,$http, dataProviderService) {
            $scope.suggestions= function(viewValue) {
                //you can call your own service call via a factory 
             return   dataProviderService.getCities(viewValue);

            };

        }]);

这是上述方法的工作示例 DEMO,希望这对您有所帮助 you.In 这种方法无论您输入的速度有多快,您总是会立即获取新结果。