如何把对AngularJS即时搜索的延迟?(How to put a delay on Angula

2019-07-21 05:27发布

我是新来AngularJS,和我有性能问题,我似乎无法应对。 我有瞬间的搜索,但它有点laggy,因为它开始在每个KEYUP搜索()。

JS:

var App = angular.module('App', []);

App.controller('DisplayController', function($scope, $http) {
$http.get('data.json').then(function(result){
    $scope.entries = result.data;
});
});

HTML:

<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:searchText">
<span>{{entry.content}}</span>
</div>

JSON数据甚至不是很大,只有300KB,我想我需要做到的是把对搜索〜1秒的延迟,以等待用户来完成的,而不是执行上的每个按键动作打字。 AngularJS做到这一点内部,以及阅读文档在这里和其他主题后,我无法找到一个明确的答案。

我很感激我如何能延缓即时搜索任何指针。 谢谢。

Answer 1:

(请参阅下面回答一个角1.3解决方案。)

这里的问题是,搜索将执行每一个模型发生变化时,这是对输入的每个KEYUP行动。

将会有简洁的方式来做到这一点,但可能是最简单的方法是将切换的结合,使该款你的过滤器操作的控制器内定义的范围$属性。 这样,你可以控制$ scope变量是如何经常更新。 事情是这样的:

JS:

var App = angular.module('App', []);

App.controller('DisplayController', function($scope, $http, $timeout) {
    $http.get('data.json').then(function(result){
        $scope.entries = result.data;
    });

    // This is what you will bind the filter to
    $scope.filterText = '';

    // Instantiate these variables outside the watch
    var tempFilterText = '',
        filterTextTimeout;
    $scope.$watch('searchText', function (val) {
        if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

        tempFilterText = val;
        filterTextTimeout = $timeout(function() {
            $scope.filterText = tempFilterText;
        }, 250); // delay 250 ms
    })
});

HTML:

<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:filterText">
    <span>{{entry.content}}</span>
</div>


Answer 2:

UPDATE

现在,比以往任何时候(角1.3)比较容易,只需添加模型上的去抖动选项。

<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">

更新plunker:
http://plnkr.co/edit/4V13gK

文档上ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions

老方法:

下面是与超越的角度本身没有依赖关系的另一种方法。

您需要设置超时时间,并且当前字符串与过去的版本进行比较,如果两者是相同的,然后它的搜索。

$scope.$watch('searchStr', function (tmpStr)
{
  if (!tmpStr || tmpStr.length == 0)
    return 0;
   $timeout(function() {

    // if searchStr is still the same..
    // go ahead and retrieve the data
    if (tmpStr === $scope.searchStr)
    {
      $http.get('//echo.jsontest.com/res/'+ tmpStr).success(function(data) {
        // update the textarea
        $scope.responseData = data.res; 
      });
    }
  }, 1000);
});

这对进入自己的看法:

<input type="text" data-ng-model="searchStr">

<textarea> {{responseData}} </textarea>

强制性plunker: http://plnkr.co/dAPmwf



Answer 3:

在角1.3我这样做:

HTML:

<input ng-model="msg" ng-model-options="{debounce: 1000}">

控制器:

$scope.$watch('variableName', function(nVal, oVal) {
    if (nVal !== oVal) {
        myDebouncedFunction();
    }
});

基本上你告诉角运行myDebouncedFunction(),味精范围变量发生变化的时候。 属性NG-模型选项=“{反跳:1000}”确保味精只能更新一次第二。



Answer 4:

 <input type="text"
    ng-model ="criteria.searchtext""  
    ng-model-options="{debounce: {'default': 1000, 'blur': 0}}"
    class="form-control" 
    placeholder="Search" >

现在,我们可以设置NG-模型选项去抖随着时间的推移,当模糊,模型需要否则就立即改变保存它有旧值,如果没有完成延迟。



Answer 5:

对于那些谁在HTML标记使用KEYUP / KEYDOWN。 这不使用手表。

JS

app.controller('SearchCtrl', function ($scope, $http, $timeout) {
  var promise = '';
  $scope.search = function() {
    if(promise){
      $timeout.cancel(promise);
    }
    promise = $timeout(function() {
    //ajax call goes here..
    },2000);
  };
});

HTML

<input type="search" autocomplete="off" ng-model="keywords" ng-keyup="search()" placeholder="Search...">


Answer 6:

去抖/节流的angularjs模型更新: http://jsfiddle.net/lgersman/vPsGb/3/

在你的情况下,有什么比在这样的的jsfiddle代码中使用指示去做:

<input 
    id="searchText" 
    type="search" 
    placeholder="live search..." 
    ng-model="searchText" 
    ng-ampere-debounce
/>

其基本上是一个小块代码由命名为“NG-安培防反跳”利用单个的角指令的http://benalman.com/projects/jquery-throttle-debounce-plugin/其可以附连到任何DOM元素。 该指令重新排序的附加事件处理程序,以便它可以控制何时节流阀事件。

你可以用它来节流/去抖*模型的角度更新*角事件处理NG- [事件] * jQuery的事件处理程序

看一看: http://jsfiddle.net/lgersman/vPsGb/3/

该指令将是Orangevolt安培框架(的一部分https://github.com/lgersman/jquery.orangevolt-ampere )。



Answer 7:

只是为用户重定向这里:

正如在介绍Angular 1.3可以使用NG-模型选项属性:

<input 
       id="searchText" 
       type="search" 
       placeholder="live search..." 
       ng-model="searchText"
       ng-model-options="{ debounce: 250 }"
/>


Answer 8:

我认为,解决这个问题的最好方法是使用本Alman的插件jQuery的油门/反跳 。 在我看来,没有必要推迟表单每一个领域的事件。

只是包装你的$ $范围观看$ .debounce这样的处理功能:

$scope.$watch("searchText", $.debounce(1000, function() {
    console.log($scope.searchText);
}), true);


Answer 9:

另一种方法是延迟功能添加到模型更新。 简单的指令似乎做了一招:

app.directive('delayedModel', function() {
    return {
        scope: {
            model: '=delayedModel'
        },
        link: function(scope, element, attrs) {

            element.val(scope.model);

            scope.$watch('model', function(newVal, oldVal) {
                if (newVal !== oldVal) {
                    element.val(scope.model);        
                }
            });

            var timeout;
            element.on('keyup paste search', function() {
                clearTimeout(timeout);
                timeout = setTimeout(function() {
                    scope.model = element[0].value;
                    element.val(scope.model);
                    scope.$apply();
                }, attrs.delay || 500);
            });
        }
    };
});

用法:

<input delayed-model="searchText" data-delay="500" id="searchText" type="search" placeholder="live search..." />

所以,你只需要使用delayed-model代替ng-model和定义所需的data-delay

演示: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p=preview



Answer 10:

我解决了这个问题与basicly它的作用是在一个特殊的属性,真正的NG-模型,我看在指令绑定,然后使用去抖服务更新我的指令属性的指令,所以对变量的用户手表他结合抖模型代替NG-模型。

.directive('debounceDelay', function ($compile, $debounce) {
return {
  replace: false,
  scope: {
    debounceModel: '='
  },
  link: function (scope, element, attr) {
    var delay= attr.debounceDelay;
    var applyFunc = function () {
      scope.debounceModel = scope.model;
    }
    scope.model = scope.debounceModel;
    scope.$watch('model', function(){
      $debounce(applyFunc, delay);
    });
    attr.$set('ngModel', 'model');
    element.removeAttr('debounce-delay'); // so the next $compile won't run it again!

   $compile(element)(scope);
  }
};
});

用法:

<input type="text" debounce-delay="1000" debounce-model="search"></input>

而在控制器:

    $scope.search = "";
    $scope.$watch('search', function (newVal, oldVal) {
      if(newVal === oldVal){
        return;
      }else{ //do something meaningful }

演示中的jsfiddle: http://jsfiddle.net/6K7Kd/37/

在$防抖动服务可以在这里找到: http://jsfiddle.net/Warspawn/6K7Kd/

通过eventuallyBind指令启发 http://jsfiddle.net/fctZH/12/



Answer 11:

角1.3将有NG-模型选项去抖,但在那之前,你必须使用一个计时器像若苏埃伊瓦拉说。 然而,在他的代码,他推出的每一个按键的计时器。 此外,他使用的setTimeout,当角一个必须使用$超时或使用$适用于setTimeout的结束。



Answer 12:

为什么大家都希望利用手表吗? 你也可以使用一个函数:

var tempArticleSearchTerm;
$scope.lookupArticle = function (val) {
    tempArticleSearchTerm = val;

    $timeout(function () {
        if (val == tempArticleSearchTerm) {
            //function you want to execute after 250ms, if the value as changed

        }
    }, 250);
}; 


Answer 13:

我觉得这里最简单的方法是预加载JSON或上一次加载$dirty ,然后过滤搜索将照顾休息。 这会为你节省额外的HTTP调用,并与预加载的数据要快得多。 记忆会受到伤害,但它是值得的。



文章来源: How to put a delay on AngularJS instant search?