我在输入上使用了反跳功能:

<input type="text"
     ng-model="model.qty"
     ng-model-options="{ debounce : 1000 }"
     min="{{model.min}}" max="{{model.max}}" step="1"
     qty-input validate-model-setting>

我有一个指令来处理禁用此输入的增量按钮和减量按钮:
app.directive('qtyInput', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, element, attrs, ngModelCtrl) {
            scope.$watch(attrs.ngModel, function(n, o) {
                var val = parseInt(n);
                if(!isNaN(val)) {
                    if(val + 1 > model.max) {
                        scope.quantityIncDisabled = true;
                    } else {
                        scope.quantityIncDisabled = false;
                    }
                    if(val - 1 < model.min) {
                        scope.quantityDecDisabled = true;
                    } else {
                        scope.quantityDecDisabled = false;
                    }
                }
            });
        }
    }
});

问题是,该指令的监视对象正在查看模型。我需要它来查看$viewValue。这是因为,由于去抖动,在输入输入和使用增量/减量按钮之间存在竞争状态。例如,您可以在输入达到1(最小)后一遍又一遍地不断单击递减按钮1秒钟,然后只有在反跳完成后,递减按钮才会被禁用。相反,我希望在输入达到1时立即禁用该按钮,而不是在等待整个反跳时间之后禁用。我最好的猜测是,这意味着将$watch放在$viewValue上,但是我不知道如何在指令中找到它。

供您引用,这些按钮本身可以通过更改输入的值然后触发输入来避免争用情况,这使得在键入输入内容和使用按钮时都可以使去抖动功能流畅地工作。
   link: function(scope, element, attrs) {
        element.bind('click', function() {
            $timeout(function() {
                var input = element.parent().find('input');
                var changingTo = parseInt(input[0].value) + parseInt(scope.inc);
                if(scope.inc < 0 || isNaN(changingTo)) {
                    var min = parseInt(input[0].min);
                    if(isNaN(changingTo)) {
                        changingTo = min;
                    } else if(changingTo < min) {
                        return;
                    }
                } else {
                    var max = parseInt(input[0].max);
                    if(changingTo > max) {
                        return;
                    }
                }
                input[0].value = String(changingTo);
                input.trigger('input');
            });
        });
    }

最佳答案

该文档的答案:https://code.angularjs.org/1.2.19/docs/api/ng/type/ngModel.NgModelController

您想像这样使用$viewChangeListeners而不是$watch(您可能需要根据反跳的方式插入$formatters):

ngModelCtrl.$viewChangeListeners.push(function(){
  var val = parseInt(ngModelCtrl.$viewValue);
  if(!isNaN(val)) {
    ...
  }
});

尽管我还没有使用过反跳选项,所以我不知道这是否可以解决您的问题,但这就是您观察viewValue的方式。

09-19 20:32