Входной сигнал углового входа [placeholder] с использованием ng-модели
Итак, первый день на работе с angularjs, и я не совсем понял. Я пытаюсь подражать html5 placeholder, используя директиву angular. Он полностью работает до тех пор, пока я не добавлю 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>
кажется супер простым, но я потерян
Ответы
Ответ 1
Всего несколько изменений в вашем примере:
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, вызывают его проверку значения модели в фокусе.
Ответ 2
Вы также можете проверить модуль Angular.JS, который реализует атрибут "placeholder" для более старых веб-браузеров:
https://github.com/urish/angular-placeholder-shim
Ответ 3
Я создал директиву-заполнителем, которая может принимать выражения углов, а также скрывает текст-заполнитель на входе. Вы можете прочитать про местозаполнитель в 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/info/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);
Это работает во всех случаях, кроме случаев копирования и вставки одного и того же текста заполнителя.