10

だから、angularjsを使った仕事の初日、私はそれをよく理解していません。angularディレクティブを使用してhtml5プレースホルダーを模倣しようとしています。フィールドに ng-model を追加するまで完全に機能し、ユーザーがフィールドを操作してフィールドの値を壊した後にのみ機能します。

ここにコードを書いてください 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>

とてもシンプルに思えますが、私は迷っています

4

3 に答える 3

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

とにかく、それが最善の解決策であるかどうかはわかりません。プレースホールド属性にあるのと同じテキストを入力しても、フォーカス時にモデルの値がチェックされます。

于 2013-02-08T17:58:04.047 に答える
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);

これは、同じプレースホルダー テキストをコピーして貼り付ける場合を除いて、すべてのケースで機能します。

于 2013-09-30T16:24:57.023 に答える