此问题与Angucomplete-alt directive
有关注意:我使用的是Angular 1.4
我正在使用remote-api-handler
参数来填充angucomplete-alt指令的选项。
如果在进行新查询后收到回复或文本字段失去焦点,我希望能够取消由angucomplete-alt 发出的查询。为此,我检查响应的配置属性,并在失去焦点时设置标志。
到目前为止,我已经设法通过向angucomplete-alt发送空数据数组来处理这种情况,但这会产生不良副作用,即显示无结果占位符并显示文本字段后面的下拉列表失去了焦点。
理想情况下,我希望实现以下目标:
如果在结果到达之前完成了新请求,则取消请求
显示text-searching
占位符而不是
text-no-results
一个。
如果失去焦点则取消请求并阻止angucomplete-alt打开其下拉列表。
我的直觉是我应该使用remote-api-handler
第二个参数(timeoutPromise
),但到目前为止我还没有成功。有人会知道如何很好地解决这个用例吗?也许你会采取与我正在尝试的策略不同的策略?
以下是定义angucomplete-alt指令的html模板的一部分:
<angucomplete-alt id="suggestions"
placeholder="Search something"
pause="100"
selected-object="vm.selected"
remote-api-handler="vm.apiHandler"
title-field="key"
minlength="1"
maxlength="70"
text-searching="search in progress"
text-no-results="nothing found"
focus-in="vm.focusIn()"
focus-out="vm.focusOut()">
</angucomplete-alt>
这是控制器处理来自angucomplete-alt:
的请求angular
.module('my-module')
.controller('FieldController', FieldController);
function FieldController(apiService) {
var self = this;
var previousSelectedTitle = '';
self.infocus = false;
self.currentString = '';
self.apiHandler = apiHandler;
self.focusIn = focusIn;
self.focusOut = focusOut;
self.selected = selected;
function apiHandler(string, timeoutPromise) {
self.currentString = string;
return apiService.get(string)
.then(function(result){
//prevents late responses to display - should use timeoutPromise?
if(!self.infocus || result.config.params.string !== self.currentString){
return {data: []};
}
else{
return result;
}
}
}
function focusIn() {
self.infocus = true;
}
function focusOut() {
self.infocus = false;
}
function selected(selectedObj) {
if (angular.isUndefined(selectedObj) ||!self.infocus) {
return;
}
//Do something great with the selected object
}
}
答案 0 :(得分:0)
自定义处理程序的第二个参数并不完全是超时承诺,而是取消承诺。仅当搜索已经在进行但用户继续输入并且现在输入已更改时,promise才得以解决。
我一直在使用Promise.race
,它似乎可以使插件正常工作:
function apiHandler(string, nevermind) {
return Promise.race([apiService.get(string), nevermind]);
}
答案 1 :(得分:0)
Tom McClure的答案几乎是正确的,有关Promise.race的正确实现,请参见下面的代码,
在控制器文件中添加以下代码
function apiHandler(string) {
return Promise.race([apiService.get(string)]);
}
在上面的代码中,promise.race将考虑需要较长时间而忽略其他API的api。
您还可以通过添加超时来取消上一个api调用,这样您将获得最新api调用的响应
var handler = $q.defer()
$http.get('url', {
timeout: handler.promise
})
要取消上一个api调用,只需调用handler.resolve()即可取消api调用
handler.resolve() //which will cancel the previous api call
这可能会对您有所帮助。