Angularjs使用ng-model输入[placeholder]指令

时间:2013-02-08 17:14:35

标签: javascript angularjs angularjs-directive

所以第一天在使用angularjs的工作,我不太明白。我正在尝试使用angular指令模仿html5占位符。它完全有效,直到我向场中添加ng模型,然后它只在用户与该字段交互后才有效,并且还会破坏该字段的任何值。

在这里编码 http://jsbin.com/esujax/32/edit


指令

App.directive('placehold', function(){
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var insert = function() {
        element.val(attrs.placehold);
      };

      element.bind('blur', function(){
        if(element.val() === '')
          insert();
      });

      element.bind('focus', function(){
        if(element.val() === attrs.placehold)
          element.val('');
      });

      if(element.val() === '')
        insert();
    }
  }
});

html

<textarea ng-model="comment" placehold="with a model it doesn't work"></textarea>

似乎超级简单,但我迷失了

3 个答案:

答案 0 :(得分:12)

您的样本中只需进行少量修改:

app.directive('placehold', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ctrl) {      

      var value;

      var placehold = function () {
          element.val(attr.placehold)
      };
      var unplacehold = function () {
          element.val('');
      };

      scope.$watch(attr.ngModel, function (val) {
        value = val || '';
      });

      element.bind('focus', function () {
         if(value == '') unplacehold();
      });

      element.bind('blur', function () {
         if (element.val() == '') placehold();
      });

      ctrl.$formatters.unshift(function (val) {
        if (!val) {
          placehold();
          value = '';
          return attr.placehold;
        }
        return val;
      });
    }
  };
});

您可以在此处进行测试:http://plnkr.co/edit/8m54JO?p=preview

不确定,它是最好的解决方案,无论如何它都有效。即使您在placehold属性中键入相同的文本,也会导致它在焦点上检查模型的值。

答案 1 :(得分:2)

您还可以签出一个Angular.JS模块,该模块为旧版Web浏览器实现“占位符”属性:

https://github.com/urish/angular-placeholder-shim

答案 2 :(得分:0)

我创建了一个占位符指令,它可以采用angularjs表达式,并在输入中隐藏占位符文本。您可以在http://blog.f1circle.com/2013/09/supporting-placeholders-in-non-html5.html

了解占位符

这是要点。

(function(angular, app) {
  "use strict";
  app.directive('placeholder',["$document", "$timeout", function($document, $timeout){
    var link = function(scope,element,attrs,ctrl){

      // if you dont use modernizr library use the solution given at
      // http://stackoverflow.com/questions/5536236/javascript-check-for-native-placeholder-support-in-ie8
      // to check if placeholder is supported natively
      if(Modernizr.input.placeholder){
        return;
      }

      /*
        The following keys all cause the caret to jump to the end of the input value
        27,  Escape
        33,  Page up
        34,  Page down
        35,  End
        36,  Home
        Arrow keys allow you to move the caret manually, which should be prevented when the placeholder is visible
        37,  Left
        38,  Up
        39,  Right
        40,  Down
        The following keys allow you to modify the placeholder text by removing characters, which should be prevented when the placeholder is visible
        8,  Backspace
        46  Delete
      */

      var pTxt, modelValue, placeholding = false, badKeys = [27,33,34,35,36,37,38,39,40,8,46];

      var unplacehold = function(){
        if(!placeholding){
          return;
        }
        placeholding = false;
        element.removeClass('placeholder');
        element.val('');
      };

      var placehold = function(){
        if(placeholding || modelValue){
          return;
        }
        placeholding = true;
        element.addClass('placeholder');
        element.val(pTxt);
      };

      var moveCaret = function(elem, index) {
        var range;
        if (elem.createTextRange) {
          range = elem.createTextRange();
          range.move("character", index);
          range.select();
        } else if (elem.selectionStart) {
          elem.focus();
          elem.setSelectionRange(index, index);
        }
      };

      attrs.$observe('placeholder',function(value){
        pTxt = value;
        placeholding = false;
        placehold();
      });

      ctrl.$parsers.unshift(function (value){
        modelValue = value;
        if(!value){
          placehold();
        }
        if(placeholding){
          return '';
        }
        return value;
      });

      ctrl.$formatters.unshift(function (value){
        if(!value){
          placehold();
          modelValue = '';
          return pTxt;
        }
        return value;
      });

      element.on('click focus contextmenu',function(event){
        if($document[0].activeElement  !== this){
          return;
        }

        if(!modelValue){
          moveCaret(this,0);
        }
      });

      element.on('blur',function(){
        placehold();
      });

      element.on('keydown',function(e){
        if(!placeholding){
          return;
        }
        if(_.contains(badKeys,e.keyCode)){
          if(e.preventDefault){
            e.preventDefault();
          }
          return false;
        }
        unplacehold();
      });

      element.on('keyup',function(e){
        if(modelValue){
          return;
        }
        placehold();
        moveCaret(this,0);
      });

      element.on('paste',function(e){
        $timeout(function(){
          modelValue = element.val();
        },0);

      });
    };

    return{
      restrict: 'A',
      require: 'ngModel',
      link : link,
      priority:3,
    };
  }]);
})(angular, app);

这适用于所有情况,除非复制并粘贴相同的占位符文本。