簡體   English   中英

我可以使用_lodash去抖動或限制AngularJS中的<input>嗎?

[英]Can I debounce or throttle a watched <input> in AngularJS using _lodash?

我有以下內容監視綁定到$ scope.id的<input>字段。 每次輸入字段值改變時,執行watch函數:

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

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

});

有沒有辦法可以對此進行超時或者使用_lodash進行去抖動,以便在用戶更改值時代碼不會在每個按鍵上執行。

我想要的是延遲一秒鍾,以便在用戶停止輸入一秒后,手表內的代碼塊運行。 請注意,輸入值可能隨時發生變化。 例如,如果值為“1”或“10”或“1000”,我需要調用該函數。 這與帶有建議的搜索框在Google中的工作方式類似。 如果用戶鍵入999,那么我需要調用該函數。 如果他刪除了9,那么它就是99,那么我需要調用該函數。

我確實有_lodash可用,因此使用它的解決方案可能最適合我的需求。

您可以在Angular 1.3.0中使用ngModelOptions

HTML:

<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>

更多信息: https//docs.angularjs.org/api/ng/directive/ngModelOptions

那你在找什么?

$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(...) as除非_.debounce函數在內部使用$timeout (據我所知,它不會do)Angular不會意識到你在$scope上所做的更改。

UPDATE

至於更新的問題 - 是的,你需要包裝整個回調函數體

$scope.$apply()

$scope.$watch("id", _.debounce(function (id) {
    // This code will be invoked after 1 second from the last time 'id' has changed.
    $scope.$apply(function(){
        // Code that does something based on $scope.id
    })
}, 1000));

我知道這個問題需要一個lodash解決方案。 無論如何這里只是一個角度解決方案:

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));

});

您可以將其封裝在指令中。 資料來源: https//gist.github.com/tommaitland/7579618

<input type="text" ng-model="id" ng-debounce="1000">

使用Javascript

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());
              });
          });
      }
  };
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM