Angularjs entrée directive rupture avec ng-modèle

Donc, le premier jour de travail avec angularjs et je ne l'ai pas tout à fait compris. J'essaie d'imiter un espace réservé html5 en utilisant une directive angulaire. Il fonctionne totalement jusqu'à ce que j'ajoute un modèle ng au champ, puis il ne fonctionne qu'après qu'un utilisateur interagit avec le champ et dégage toutes les valeurs du champ.

Code ici http://jsbin.com/esujax/32/edit


La directive

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(); } } }); 

Le html

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

Semble super simple mais je suis perdu

Juste quelques modifications dans votre échantillon:

 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; }); } }; }); 

Vous pouvez le tester ici: http://plnkr.co/edit/8m54JO?p=preview

Pas sûr, que c'est la meilleure solution, de toute façon, ça marche. Même si vous tapez le même texte, que vous avez dans votre attribut de localisation, faites vérifier la valeur du modèle sur la mise au point.

Vous pouvez également consulter un module Angular.JS qui implémente l'attribut "espace réservé" pour les navigateurs Web plus anciens:

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

J'ai créé une directive d'espace réservé qui peut prendre des expressions angularjs et masquer le texte de l'espace réservé sur l'entrée. Vous pouvez lire à propos de l'espace réservé à http://blog.f1circle.com/2013/09/supporting-placeholders-in-non-html5.html

Voici l'essentiel.

 (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); 

Cela fonctionne sur tous les cas, sauf lorsque vous copiez et collez le même texte d'espace réservé.