Javascript ng变更延迟,angularjs

Javascript ng变更延迟,angularjs,javascript,html,angularjs,Javascript,Html,Angularjs,我正在用angularjs开发一个应用程序,它在屏幕上用数字数据显示一些文本字段。它们看起来很像这样: <input type="text" ng-model="value" ng-change="controller.functions.valueChanged(value)"> 问题是每次我写一个数字或从textfield中删除一个数字时,都会调用函数的change指令。是否可以对ng change函数应用某种延迟?最简单的方法是在controller.functions.

我正在用angularjs开发一个应用程序,它在屏幕上用数字数据显示一些文本字段。它们看起来很像这样:

<input type="text" ng-model="value" ng-change="controller.functions.valueChanged(value)">


问题是每次我写一个数字或从textfield中删除一个数字时,都会调用函数的change指令。是否可以对ng change函数应用某种延迟?

最简单的方法是在controller.functions.valueChanged函数中设置超时

Angularjs有ngModelOptions指令,它对这类事情非常有用。你可以试着设置

ng-model-options="{ debounce: 1000 }"
用于更改模型之前的超时。你也可以使用

ng-model-options="{ updateOn: 'blur' }"
仅在焦点离开元素时更新模型。

您可以使用

去抖动:整数值,包含以毫秒为单位的去抖动模型更新值。值为0将触发立即更新

代码


已更新

您可以使用$timeout服务创建延迟函数。这可以应用于其他指令回调

angular.module('myApp',[]);
angular.module('myApp')
.controller('myCtrl'、[“$scope”、“$log”、“$timeout”,
函数($scope、$log、$timeout){
$scope.delay=(函数(){
var-promise=null;
返回函数(回调,毫秒){
$timeout.cancel(promise);//cleartimout(timer);
promise=$timeout(回调,毫秒);//timer=setTimeout(回调,毫秒);
};
})();
$scope.doSomeThing=函数(值){
var current=新日期();
$scope.result='值:'+$scope.foo+',上次更新:'+当前;
};
}
]);

$timeout-delay演示
结果:{{Result}}

我正在使用AngularJs 1.2.x,偶然发现了每次更改都会触发的ng更改问题。可以使用ng blur,但即使值没有更改,它也会激发。因此,两者都不能有效利用

有了Angularjs 1.3.x,使用
ng模型选项就更容易了,如下所示

调用更改函数“onBlur”

ng change=“ctrl.onchange()”ng model options=“{updateOn:'blur'}”

将更改功能的调用延迟500毫秒

ng change=“ctrl.onchange()”ng模型选项='{debounce:500}'

现在回到使用AngularJs 1.2.x获得这些东西的问题

调用更改函数“onBlur”

html

JS

app.directive('sdChangeOnBlur', function() {
  return {
    restrict: 'A',
    scope: {
      sdChangeOnBlur: '&'
    },
    link: function(scope, elm, attrs) {
      if (attrs.type === 'radio' || attrs.type === 'checkbox')
        return;

      var parameters = getParameters(attrs.sdChangeOnBlur);

      var oldValue = null;
      elm.bind('focus', function() {
        scope.$apply(function() {
          oldValue = elm.val();
        });
      })
    
      elm.bind('blur', function() {
        scope.$apply(function() {
          if (elm.val() != oldValue) {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChangeOnBlur();
            } else {
              scope.sdChangeOnBlur(params)
            }
          }
        });
      });
    }
  };
});

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}
app.directive('sdChange', ['$timeout',
  function($timeout) {
    return {
      restrict: 'A',
      scope: {
        sdChange: '&',
        sdChangeDelay: '@' //optional
      },
      link: function(scope, elm, attr) {
        if (attr.type === 'radio' || attr.type === 'checkbox') {
          return;
        }

        if (!scope.sdChangeDelay) {
          scope.sdChangeDelay = 500; //defauld delay
        }

        var parameters = getParameters(attr.sdChange);

        var delayTimer;
        elm.bind('keydown keypress', function() {
          if (delayTimer !== null) {
            $timeout.cancel(delayTimer);
          }

          delayTimer = $timeout(function() {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChange();
            } else {
              scope.sdChange(params)
            }
            delayTimer = null;
          }, scope.sdChangeDelay);

          scope.$on(
            "$destroy",
            function(event) {
              $timeout.cancel(delayTimer);
              console.log("Destroyed");
            }
          );
        });
      }
    };
  }
]);

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}
app.directive('sdchangeonflur',function(){
返回{
限制:“A”,
范围:{
sdChangeOnBlur:“&”
},
链接:功能(范围、elm、属性){
如果(attrs.type=='radio'| | attrs.type==='checkbox')
返回;
var参数=getParameters(attrs.sdchangeonflur);
var oldValue=null;
elm.bind('focus',function(){
作用域$apply(函数(){
oldValue=elm.val();
});
})
elm.bind('blur',function(){
作用域$apply(函数(){
if(elm.val()!=oldValue){
var params={};
如果(parameters&¶meters.length>0){
对于(var n=0;n
将更改功能的调用延迟500毫秒

html

JS

app.directive('sdChangeOnBlur', function() {
  return {
    restrict: 'A',
    scope: {
      sdChangeOnBlur: '&'
    },
    link: function(scope, elm, attrs) {
      if (attrs.type === 'radio' || attrs.type === 'checkbox')
        return;

      var parameters = getParameters(attrs.sdChangeOnBlur);

      var oldValue = null;
      elm.bind('focus', function() {
        scope.$apply(function() {
          oldValue = elm.val();
        });
      })
    
      elm.bind('blur', function() {
        scope.$apply(function() {
          if (elm.val() != oldValue) {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChangeOnBlur();
            } else {
              scope.sdChangeOnBlur(params)
            }
          }
        });
      });
    }
  };
});

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}
app.directive('sdChange', ['$timeout',
  function($timeout) {
    return {
      restrict: 'A',
      scope: {
        sdChange: '&',
        sdChangeDelay: '@' //optional
      },
      link: function(scope, elm, attr) {
        if (attr.type === 'radio' || attr.type === 'checkbox') {
          return;
        }

        if (!scope.sdChangeDelay) {
          scope.sdChangeDelay = 500; //defauld delay
        }

        var parameters = getParameters(attr.sdChange);

        var delayTimer;
        elm.bind('keydown keypress', function() {
          if (delayTimer !== null) {
            $timeout.cancel(delayTimer);
          }

          delayTimer = $timeout(function() {
            var params = {};
            if (parameters && parameters.length > 0) {
              for (var n = 0; n < parameters.length; n++) {
                params[parameters[n]] = scope.$parent.$eval(parameters[n]);
              }
            } else {
              params = null;
            }

            if (params == null) {
              scope.sdChange();
            } else {
              scope.sdChange(params)
            }
            delayTimer = null;
          }, scope.sdChangeDelay);

          scope.$on(
            "$destroy",
            function(event) {
              $timeout.cancel(delayTimer);
              console.log("Destroyed");
            }
          );
        });
      }
    };
  }
]);

function getParameters(functionStr) {
  var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')'));
  var params;
  if (paramStr) {
    params = paramStr.split(",");
  }
  var paramsT = [];
  for (var n = 0; params && n < params.length; n++) {
    paramsT.push(params[n].trim());
  }
  return paramsT;
}
app.directive('sdChange',['$timeout',
函数($timeout){
返回{
限制:“A”,
范围:{
sdChange:“&”,
sdChangeDelay:'@'//可选
},
链接:功能(范围、elm、属性){
如果(attr.type=='radio'| | attr.type==='checkbox'){
返回;
}
如果(!scope.sdChangeDelay){
scope.sdChangeDelay=500;//定义延迟
}
var参数=getParameters(attr.sdChange);
无功延时定时器;
elm.bind('keydown keypress',function(){
if(delayTimer!==null){
$timeout.cancel(延迟计时器);
}
delayTimer=$timeout(函数(){
var params={};
如果(parameters&¶meters.length>0){
对于(var n=0;n
两种方法的PLNKR均为

如果我这样做