2014-11-24 76 views
5

我正在開發一個帶有angularjs的應用程序,它在屏幕上用數字數據顯示一些文本字段。他們看起來很喜歡這個:ng-change delay,angularjs

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

的問題是,每次我寫一個數字或者我從文本字段刪除某個號碼,NG-改變指令調用的函數。是否有可能在ng-change函數中應用一些延遲王?

回答

7

更新

可以使用$超時服務,創建延時功能。這可以

angular.module('myApp', []); 
 
angular.module('myApp') 
 
    .controller('myCtrl', ["$scope", "$log", "$timeout", 
 
    function($scope, $log, $timeout) { 
 

 
     $scope.delay = (function() { 
 
     var promise = null; 
 
     return function(callback, ms) { 
 
      $timeout.cancel(promise); //clearTimeout(timer); 
 
      promise = $timeout(callback, ms); //timer = setTimeout(callback, ms); 
 
     }; 
 
     })(); 
 

 
     $scope.doSomeThing = function(value) { 
 
     var current = new Date(); 
 
     $scope.result = 'value:' + $scope.foo + ', last updated:' + current; 
 
     }; 
 

 
    } 
 
    ]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script> 
 
<div ng-app="myApp" ng-controller="myCtrl"> 
 
    <h3>$timeout delay demo</h3> 
 
    <div> 
 
    <input ng-model="foo" ng-change="delay(doSomeThing, 1000)" type="text" /> 
 
    </div> 
 
    <div>Result: {{result}}</div> 
 
</div>

+0

我已經實現了這個方法,並且將延遲增加到了3000,並且執行了任何操作,你確定沒關係嗎? – 2014-11-24 07:59:30

+0

更新了代碼片段中的演示。回調函數應該解析爲參數。 – aifarfa 2014-11-24 08:55:46

+0

似乎更好,是否有可能發送參數做一些事情?在ng-change調用中,它看起來像一個參數,不像函數調用 – 2014-11-24 09:08:04

2

最簡單的方法是在controller.functions.valueChanged函數中設置一個超時值。

Angularjs有ngModelOptions指令,這對於這類事情非常有用。您可以嘗試設置

ng-model-options="{ debounce: 1000 }" 

用於模型更改之前的超時。您也可以使用

ng-model-options="{ updateOn: 'blur' }" 

僅在焦點離開元素時更新模型。

+0

如果我和NG-模式選項做,模型等待改變,但controller.functions.valueChanged當我在textfield中改變某些東西時,函數會立即被調用,所以它不適用於我。我如何添加超時功能? – 2014-11-24 07:48:14

16

您可以使用ngModelOptions

防抖動:其中包含以毫秒爲單位去抖模型更新值的整數值。值爲0會觸發立即更新。

代碼

<input type="text" ng-model-options="{ debounce: 1000 }" ng-model="value" ng-change="controller.functions.valueChanged(value)"> 
+0

@ m.dorian - 這個答案好多了。我認爲你應該改變這個接受的答案。 – kapad 2015-10-29 14:57:53

2

我使用AngularJs的1.2.x和射擊時每變化的NG-變化問題絆倒被應用到其他指令回調。可以使用ng-blur,但即使值沒有變化,也會觸發。所以兩者都無法有效使用。

隨着Angularjs 1.3.x中,事情更容易使用ng-model-options像下面

調用切換功能 「的onblur」

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

而且

延遲變化的調用功能500ms

ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"

現在回到使用AngularJs 1.2獲得這樣的東西的問題。X

調用改變功能 「的onblur」

HTML

<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange()" />

<input type="text" ng-model="ctrl.a.c" sd-change-on-blur="ctrl.onchange(ctrl.a.c)" />

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

由500ms的

HTML來拖待變函數的調用

<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>

OR

<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>

個JS

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

plnkrs兩種方法都是

http://plnkr.co/edit/r5t0KwMtNeOhgnaidKhS?p=preview

http://plnkr.co/edit/9PGbYGCDCtB52G8bJkjx?p=info