使用ng-maxlength时,不会触发监听器

时间:2014-08-21 16:34:58

标签: javascript angularjs angularjs-directive angularjs-validation

我有一个基本上监视元素值的指令。

此元素具有ng-maxlength属性,设置为150.当我传递150个字符时,不再触发$watch。此外,当我用ctrl + x删除整个文本时,再次不会触发$watch

输入元素

<input type="text" ng-model="company.fullName" name="companyFullName" required ng-maxlength="150" ng-input-validate />

指令

enlabApp.directive('ngInputValidate', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            scope.$watch(function () { return ctrl.$modelValue; }, function (value) {
                 console.log('test');
            });
        }
    };
});

当我删除ng-maxlength指令时,问题就消失了。

2 个答案:

答案 0 :(得分:4)

您正在使用ng-maxlength=150,这意味着angular将对字符数进行验证,并相应地更新$modelValue。无效时(如果长度超过)$modelValue的含义为undefined,然后通过执行ctl-x删除值,然后消化循环运行,模型值再次变为undefined因为没有值存在并且与之前的值没有差别且观察者没有触发(仅当modelValue变脏时,观察者才会触发)。

所以请使用$viewValueelement[0].value(我不建议)。所以: -

        scope.$watch(function () { 
          return ctrl.$viewValue; 
        }, function (value) {
          console.log('Triggered');
        });
  • $ viewValue:视图中的实际字符串值。
  • $ modelValue:模型中控件绑定的值。

请注意,使用ng-minlength仅用于验证它不会限制用户输入/粘贴更多字符,如果您想限制minlength属性是要走的路

另请注意,您无需在ngModel上注册手表,也可以使用$viewChangeListeners,而不是创建额外的手表。

  

视图值更改时要执行的函数数组。它被调用时没有参数,它的返回值被忽略。这可用于代替模型值的额外$ watch。

ctrl.$viewChangeListeners.push(function(){//... });

答案 1 :(得分:0)

而不是$watch,您可以使用element.bind“输入”事件。喜欢看:

  element.bind "input", ->
    ctrl.$modelValue

如果更新ctrl,则必须使用$ scope。$ apply()来更新视图:

  element.bind "input", ->
    $scope.$apply ->
      ctrl.$modelValue

这是我使用它的例子:

link: ($scope, element, attrs, ngModelController) ->

  element.bind "focus", ->
    if not ngModelController.pristineBlur and not ngModelController.dirtyBlur
      ngModelController.pristineFocus = on
    else 
      ngModelController.dirtyFocus = on
      ngModelController.pristineBlur = off
      ngModelController.dirtyBlur = off
    ngModelController.focus = on
    updateController()

  element.bind "blur", ->
    if ngModelController.pristineFocus
      ngModelController.pristineBlur = on
      ngModelController.pristineFocus = off
    else
      ngModelController.dirtyBlur = on
      ngModelController.dirtyFocus = off
    ngModelController.focus = off
    updateController()

  element.bind "input", ->
    updateController()

  updateController = ->
    $scope.$apply ->
      ngModelController.pristineFocusOrValid = ( ngModelController.pristineFocus and ngModelController.pristineFocus or ngModelController.pristineFocus and ngModelController.$valid ) or ( ngModelController.focus and ngModelController.$valid )
      ngModelController.minlengthWarning = ( ( ngModelController.pristineBlur or ngModelController.dirtyFocus or ngModelController.dirtyBlur ) and ngModelController.$viewValue and ngModelController.$invalid ) or ngModelController.dirtyFocus and ngModelController.$invalid
      ngModelController.isRequiredError = ( ngModelController.pristineBlur or ngModelController.dirtyBlur ) and not ngModelController.focus and not ngModelController.$viewValue