在属性指令中创建禁用绑定

时间:2016-08-11 20:23:50

标签: javascript html angularjs

我正在尝试创建一个非常简单的字符计数器指令,我可以在任何textareainput上删除一个属性,并轻松地让input/textarea服从对象ng-maxlength并且能够阻止在该点之后键入并在input/textarea之后追加一个字符倒计时的简单span元素。

我现在要弄清楚的是,一旦达到最大字符数,我将如何绑定要禁用的input/textarea的禁用状态

angular.module('bidrAdminApp')
  .directive('characterCounter', function ($compile) {
    return {
      restrict: 'A',
      scope: {
        characterCount: '=ngModel',
        maxLength: '=ngMaxlength'
      },
      link: function postLink(scope, element, attrs) {
        console.log(attrs);
        var el = '<i>{{maxLength - characterCount.length}}</i>';
        el = $compile(el)(scope);
        $(element).after(el);
      }
    };
  });

到目前为止,模板非常简单

4 个答案:

答案 0 :(得分:2)

我不建议注册任何$watcher。在您的情况下,一个简单的事件监听器就足够了:

&#13;
&#13;
angular
  .module('app', [])
  .directive('myMaxCount', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attr) {
      var max = attr.myMaxCount;
      
      element.on('keydown', keydownHandler);
      scope.$on('$destroy', function () {
        element.off('keydown', keydownHandler);
      });      
      
      function keydownHandler (e) {
        if(e.target.value.length + 1 > max) {
          e.preventDefault();
        }
      }
    }
  };
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <input type="text" my-max-count="5"/>
</div>
&#13;
&#13;
&#13;

这是不要对你的$digest周期进行评估的方式:) 请注意,您必须取消注册侦听器以防止内存泄漏。

答案 1 :(得分:0)

你需要在模型中添加一个观察者,然后在那里做你的逻辑......

angular.module('myApp', [])
  .directive('characterCounter', function($compile) {
    return {
      restrict: 'A',
      scope: {
        characterCount: '=ngModel',
        maxLength: '=ngMaxLength'
      },
      link: function postLink(scope, element, attrs) {
        var el = '<i>{{maxLength - characterCount.length}}</i>';
        el = $compile(el)(scope);
        $(element).after(el);
        $(element).attr('max', scope.maxLength);
        /*
        scope.$watch('characterCount', function(newVal, oldVal) {
          if(!newVal) return;
          
          if(newVal.length >= scope.maxLength) {
            $(element).attr('disabled', 'disabled');
          } else {
            $(element).removeAttr('disabled');
          }
        })*/

        // if you don't want the disabled attribute:

        scope.$watch('characterCount', function(newVal, oldVal) {
          if (!newVal) return;

          if (newVal.length > scope.maxLength) {
            scope.characterCount = oldVal;
          }
        })
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  
  <label>With input</label> <br/>
  <input type="text" character-counter ng-model="model" ng-max-length="10"/>
  <br/><br/>
  
  <label>With textArea</label><br/>
  <textarea character-counter ng-model="textArea" ng-max-length="10">
  
  </textarea>
</div>

答案 2 :(得分:0)

我添加了一个新的scope.$watch函数,该函数将监视characterCount值并在更改时运行函数。在这种情况下,它会将长度修剪为maxLength,这将适用于键入和复制/粘贴到文本字段。如果您使用长度超过maxLength的值在控制器中手动设置值,它也会起作用。

angular.module('bidrAdminApp')
  .directive('characterCounter', function ($compile) {
    return {
      restrict: 'A',
      scope: {
        characterCount: '=ngModel',
        maxLength: '=ngMaxlength'
      },
      link: function postLink(scope, element, attrs) {
        console.log(attrs);
        var el = '<i>{{maxLength - characterCount.length}}</i>';
        el = $compile(el)(scope);
        $(element).after(el);

        scope.$watch('characterCount', function(newVal, oldVal) {
            scope.characterCount = scope.characterCount.substr(0, scope.maxLength);
        });
      }
    };
  });

答案 3 :(得分:0)

已经有很多答案,但我认为最好不要在angular指令中使用任何Jquery,因为它很难测试。这是一个使用$ watch完成同样工作的解决方案。

result
app = angular.module("bidrAdminApp", [])
  .directive('characterCounter', function($compile) {
    return {
      restrict: 'A',
      scope: {
        characterCount: '=ngModel',
        lengthLimit: '=lengthLimit'
      },
      link: function(scope, ele, attrs) {
        scope.$parent.count = attrs.lengthLimit;
        scope.$watch("characterCount", function(newvalue, oldvalue) {
          if (newvalue) {
            scope.$parent.count = attrs.lengthLimit - newvalue.length;
            if (newvalue.length >= attrs.lengthLimit) {
              scope.$parent.disabled = true;
            }
          }
        })
      }
    };
  });