当用户键入速度非常快时,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 这种方法无论您输入的速度有多快,您总是会立即获取新结果。
我正在使用 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 这种方法无论您输入的速度有多快,您总是会立即获取新结果。