Angularjs:如何在输入时输入[text] ngModel延迟值

Sti*_*ger 19 javascript angularjs

我有一个带ngModel绑定的文本框,如下所示:

<input type="text" ng-model="typing" />

和这个texbox的价值

value: {{ typing }}

我希望模型延迟在我输入时更新值.也许如果我停止输入500ms,模型将更新所有值(我在文本框中键入的所有内容).我做了一些谷歌,但没有运气.安永有什么想法?请帮忙.

编辑

这个Angularjs:input [text] ngChange在值发生变化时触发,不能为我的情况提供解决方案.它会在模糊后带来解决方案更新值,但我希望在停止输入后更新值,而不是模糊文本框.

编辑2(答案)

对于角度版本1.4,指令ngModelOptions在我的情况下很有用.我可以像这样编写,<input ng-model="typing" ng-model-options="{ updateOn: 'default', debounce: {'default': 500, 'blur': 0} }" />将更新值延迟到默认的500ms模型,如果丢失焦点则立即更新.

Pet*_*ter 30

处理这个的最整洁的方法可能是编写一个包装<input>元素的指令并添加延迟行为.这是我为同一目的而写的指令:

angular.module('MyModule')
    .directive('easedInput', function($timeout) {
        return {
            restrict: 'E',
            template: '<div><input class="{{externalClass}} my-eased-input" type="text" ng-model="currentInputValue" ng-change="update()" placeholder="{{placeholder}}"/></div>',
            scope: {
                value: '=',
                timeout: '@',
                placeholder: '@',
                externalClass: '@class'
            },
            transclude: true,
            link: function ($scope) {
                $scope.timeout = parseInt($scope.timeout);
                $scope.update = function () {
                    if ($scope.pendingPromise) { $timeout.cancel($scope.pendingPromise); }
                    $scope.pendingPromise = $timeout(function () { 
                        $scope.value = $scope.currentInputValue;
                    }, $scope.timeout);
                };
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

该指令将在您的HTML中调用,如下所示:

<eased-input value="myValue" timeout="500" placeholder="Please enter text..." />
Run Code Online (Sandbox Code Playgroud)

解剖指令:

超时服务

该指令使用angular的$timeout服务来处理时间:它是一种可注入的,可模拟的,惯用的替代方法setTimeout.此服务注入指令构造函数.

属性

该指令接受三个属性:value,timeoutplaceholder.

value这里的属性绑定到控制器范围内的变量,该控制器拥有封闭的"上下文".在这种情况下,它绑定到myValue,即$scope.myValue在任何控制器负责此代码.它具有双向绑定,由指令属性中的'='条目表示scope.这意味着当该指令更新时value,更改将传播到拥有该指令的控制器; 因此,在指令内部$scope.myValue更改时value会发生变化.

timeoutplaceholder属性具有单向绑定:该指令从属性读取它们的值,但不会改变它们.它们是有效的配置值.

HTML模板

template对指令属性表示,将在其位置上产生一次角度编译和链接的HTML.它基本上只是一个input具有一些特殊和不那么特殊属性的元素.输入框中的值绑定到currentInputValue指令$scopevia 上的变量ng-model.该change输入框事件被绑定到update对指令的功能$scope通过ng-change指令.

链接功能

该过程的核心在于link指令的功能:我们定义一个update方法.如上所述,此方法绑定到change指令的HTML模板中的输入框的事件.因此,每次用户改变框中的输入时,都会update被调用.

此方法使用该$timeout服务.它告诉$timeout服务等待timeout毫秒,然后应用设置的回调$scope.value = $scope.currentInputValue.这与调用类似setTimeout(function () {$scope.value = $scope.currentInputValue}, timeout).

$timeout调用返回一个promise.我们可以通过调用取消等待执行的p生成的承诺.这就是它的第一行:如果我们有一个先前更改事件的承诺,我们在创建新事件之前取消它.这意味着如果我们有例如500ms超时,并且更新被调用两次,并且调用400ms,我们将只有一个等待触发的承诺.$timeout$timeout.cancel(p)update

总体结果

这个承诺一旦解决就会确定$scope.value = currentInputValue; 即它将"向外可见" value属性设置为具有输入框内容的值.value只会改变 - 外部控制器只能看到value变化 - 在静止的timeout毫秒之后,我相信这是你所追求的行为.


Mic*_*ord 11

如果您可以在模型中使用第二个属性,则可以$scope.$watchdebounce函数一起使用:

HTML

<input type="text" ng-model="typing" />
<input type="text" value="{{ typed }}" />
Run Code Online (Sandbox Code Playgroud)

使用Javascript

$scope.$watch('typing', debounce(function() {
    $scope.typed = $scope.typing;
    $scope.$apply();
}, 500));
Run Code Online (Sandbox Code Playgroud)

您可以编写自己的去抖功能,也可以使用现有功能.有一个良好的执行这里,或者,如果你碰巧使用undescore.js,你已经设置.

这是一个jsFiddle示例.

更新: Angular 1.3现在有一种内置的方式去除用户输入:ngModelOptions.