Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以对手表进行去盎司或节流吗<;输入>;在AngularJS中使用lodash?_Javascript_Angularjs_Lodash - Fatal编程技术网

Javascript 我可以对手表进行去盎司或节流吗<;输入>;在AngularJS中使用lodash?

Javascript 我可以对手表进行去盎司或节流吗<;输入>;在AngularJS中使用lodash?,javascript,angularjs,lodash,Javascript,Angularjs,Lodash,我有以下代码,它在绑定到$scope.id的字段上进行监视。每次输入字段值更改时,都会执行watch函数: $scope.$watch("id", function (id) { // code that does something based on $scope.id }); 有没有一种方法我可以在这个上面加一个超时或者用_lodash去抖动这个,这样代码 当用户更改值时,不会在每次按键时执行 我想要的是一个 延迟一秒钟,以便在用户停止键入一秒钟后 手表内的代码块将运行。请注意,

我有以下代码,它在绑定到$scope.id的
字段上进行监视。每次输入字段值更改时,都会执行watch函数:

$scope.$watch("id", function (id) {

   // code that does something based on $scope.id

});
有没有一种方法我可以在这个上面加一个超时或者用_lodash去抖动这个,这样代码 当用户更改值时,不会在每次按键时执行

我想要的是一个 延迟一秒钟,以便在用户停止键入一秒钟后 手表内的代码块将运行。请注意,输入值是可以随时更改的。例如,如果值为“1”或“10”或“1000”,则需要调用该函数。这类似于谷歌搜索框的工作方式。如果用户键入999,则需要调用该函数。如果他删除了一个9,所以是99,那么我需要调用这个函数


我确实有可用的lodash,因此使用它的解决方案可能最适合我的需要

这就是你要找的吗

$scope.$watch("id", _.debounce(function (id) {
    // Code that does something based on $scope.id
    // This code will be invoked after 1 second from the last time 'id' has changed.
}, 1000));
但是,请注意,如果要在该函数中更改$scope,则应将其包装为
$scope。$apply(…)
,除非
\uoBounce
函数在内部使用
$timeout
(据我所知,它没有这样做),Angular将不会知道您对
$scope
所做的更改

更新

至于更新的问题-是的,您需要用

$scope.$apply()


您可以将其封装在指令中。资料来源:


您可以在Angular 1.3.0中使用ngModelOptions

HTML:


姓名:
清除
user.name=

更多信息:

我知道这个问题需要一个lodash解决方案。无论如何,这里有一个角度唯一的解决方案:

app.controller('BlaCtrl', function(debounce) {

    $scope.$watch("id", debounce(function (id) {
        ....
    }, 1000));

});
在控制器中:


瓦伊达-是的,我认为这是需要的,但我不确定我应该使用去盎司还是油门?我试图寻找一些例子,但没有太多。你认为节流阀在这里会实现什么?可以用电梯类比来描述
debounce
throttle
之间的区别。如果有几个人进入电梯,除非有足够的时间关门,否则电梯不会运行——这是“去盎司”。如果电梯很小,有太多的人想进入,它最终必须运行(比如说最多有5人)-这是“油门”,我更新了问题,以显示你的建议。我应该将所有内容都包装在$scope.$apply()中,还是可以在代码末尾和函数中运行$scope.$apply()?因此,如果您想在用户键入时永远等待,请使用
debounce'。如果您希望在最大延迟后执行操作,即使用户没有停止键入-使用
throttle`我已经更新了答案-是的,最好用$apply包装代码。这是推荐的方法。只有在代码块中没有抛出异常并且实际调用了$apply()时,最后调用$apply()才有效。在这方面,用$apply()包装代码是安全的-Angualar将知道代码中发生了什么。如果您能够使用Angular 1.3,这绝对是一种方法!但是,它不应该更像
var args=arguments;timeout=$timeout(函数(){callback.apply(this,args);},interval)?id参数将无法用您的代码定义,并且将完全丢失。是的,您是对的,谢谢。在简单的监视中,您可以只从范围中获取值,但当然最好将参数传递给回调。
<input type="text" ng-model="id" ng-debounce="1000">
app.directive('ngDebounce', function ($timeout) {
  return {
      restrict: 'A',
      require: 'ngModel',
      priority: 99,
      link: function (scope, elm, attr, ngModelCtrl) {
          if (attr.type === 'radio' || attr.type === 'checkbox') {
              return;
          }

          var delay = parseInt(attr.ngDebounce, 10);
          if (isNaN(delay)) {
              delay = 1000;
          }

          elm.unbind('input');

          var debounce;
          elm.bind('input', function () {
              $timeout.cancel(debounce);
              debounce = $timeout(function () {
                  scope.$apply(function () {
                      ngModelCtrl.$setViewValue(elm.val());
                  });
              }, delay);
          });
          elm.bind('blur', function () {
              scope.$apply(function () {
                  ngModelCtrl.$setViewValue(elm.val());
              });
          });
      }
  };
});
<div ng-controller="Ctrl">
  <form name="userForm">
    Name:
    <input type="text" name="userName"
           ng-model="user.name"
           ng-model-options="{ debounce: 1000 }" />
    <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button><br />
  </form>
  <pre>user.name = <span ng-bind="user.name"></span></pre>
</div>
app.factory('debounce', function($timeout) {
    return function(callback, interval) {
        var timeout = null;
        return function() {
            $timeout.cancel(timeout);
            var args = arguments;
            timeout = $timeout(function () { 
                callback.apply(this, args); 
            }, interval);
        };
    }; 
}); 
app.controller('BlaCtrl', function(debounce) {

    $scope.$watch("id", debounce(function (id) {
        ....
    }, 1000));

});