简体   繁体   English

AngularJS-使用$ http和去抖动处理动态搜索

[英]AngularJS - Handling dynamic search using $http and debounce

I have a text input below, bound to a model req.mod1 , with a debounce delay in updating model, that calls a pullData() function. 我在下面有一个文本输入,该文本输入绑定到模型req.mod1 ,在更新模型时会出现反跳延迟,该函数会调用pullData()函数。

<input type="text" class="form-control" ng-change="pullData()" ng-model-options="{debounce: 1000}" ng-model="req.mod1">

Inside of pullData() I have a simple $http.get request, that pulls data and updates some other fields in the form. pullData()内部,我有一个简单的$http.get请求,该请求提取数据并更新表单中的其他一些字段。

$scope.pullData = function(){
    var pullingData = true;
    if (!pullingData){
        $http.get('example.com/search/' + $scope.req.mod1 ).then(res)
            ...
            $scope.req.mod2 = res.data.mod2;
            $scope.req.mod3 = res.data.mod3;
            var pullingData = false;
            ...
    }
}

The problem that arises is that multiple calls stack on top of each other -- I think -- and so if a user happens to input text, wait >1second, and type some more, the call would go out with the first inputted text. 出现的问题是,多个调用彼此叠加(我认为),因此,如果用户碰巧输入文本,等待> 1秒,然后键入更多内容,则该调用将与输入的第一个文本一起消失。 Then it would pull the data and update the form with the first res . 然后它将提取数据并使用第一个res更新表单。 I'm trying to keep track of the request with a pullingData var. 我正在尝试使用pullingData var跟踪请求。

Any ideas on how to handle a truly dynamic search call? 关于如何处理真正的动态搜索调用的任何想法? Is there a way to cancel requests if a new one comes in? 如果有新请求,是否可以取消请求? Or maybe just tell angular to constantly overwrite it? 还是只是告诉角度来不断覆盖它?

Thanks in advance. 提前致谢。

I think this is what you need http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx 我认为这是您需要的http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx

When you create a request.. it's called Promise , so what you need to cancel is that. 当您创建请求时,它称为Promise ,因此您需要取消的是。

Something like this: 像这样:

app.factory("movies", function($http, $q){
    var getById = function(id){
        var canceller = $q.defer();
        var cancel = function(reason){
            canceller.resolve(reason);
        };
        var promise = $http.get("/api/movies/slow/" + id, { timeout: canceller.promise})
                .then(function(response){
                   return response.data;
                });
        return {
            promise: promise,
            cancel: cancel
        };
    };
    return {
        getById: getById
    };
});

When the user enters something to search, your app should always search by the user's input. 当用户输入要搜索的内容时,您的应用应始终根据用户的输入进行搜索。 It means that you shouldn't cancel the user's input. 这意味着您不应该取消用户的输入。

For example, the user want to search something about 'starwar', when he/she enter 'star', and you get some result. 例如,当用户输入“ star”时,他想搜索有关“ starwar”的信息,那么您会得到一些结果。 If now you cancel the 'war' which is entered after, the result is not good. 如果现在您取消之后输入的“战争”,结果将是不好的。 So just let Angular override the result. 因此,只要让Angular覆盖结果即可。

Moreover, some errors in your example of code, when you call pullData , it never passes the if check: 此外,在代码示例中,当您调用pullData时,某些错误永远不会通过if检查:

$scope.pullData = function(){
    var pullingData = true;
    // !pullingData is always false
    if (!pullingData){
        $http.get('example.com/search/' + $scope.req.mod1 ).then(res)

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM