我有一个货币输入指令。它执行一些基本的数字验证,$parse
- 返回一个数字。另外,我想在输入之前使用CSS $
放置:before
。问题是,您无法在:before
元素上使用<input>
。
我的解决方案是创建以下指令(为简单起见,我除了required
之外还删除了验证):
angular.module('myApp')
.directive('myCurrencyInput', function () {
return {
restrict: 'A',
require: ['ngModel', '^form'],
scope: {
ngModel: '='
},
replace: true,
templateUrl: 'scripts/directives/myCurrencyInput/myCurrencyInput.html',
compile: function(element, attrs) {
// The internal input to the directive
var $input = element.children('input');
if(attrs.required) {
element.removeAttr('required');
attrs.required = undefined;
$input.attr('required', 'required');
}
if(attrs.name) {
element.removeAttr('name');
$input.attr('name', attrs.name);
attrs.name = undefined;
}
return function postLink(scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0];
var formCtrl = ctrls[1];
var internalCtrl = element.find('input').controller('ngModel');
if($input.attr('required') === 'required') {
// formCtrl doesn't have ngModelCtrl attached at this point
formCtrl.$removeControl(ngModelCtrl);
}
// Bind internal model changes to the outside ngModel
scope.$watch('internalModel', function(newVal) {
if(newVal !== undefined && newVal !== scope.ngModel) {
scope.ngModel = newVal;
}
});
// Bind external model changes to the inside ngModel (internalModel)
scope.$watch('ngModel', function(newVal) {
if(newVal !== undefined && newVal !== scope.internalModel) {
scope.internalModel = newVal;
}
});
};
}
};
});
模板scripts/directives/myCurrencyInput/myCurrencyInput.html
是:
<div class="my-currency-input">
<input type="text" ng-model="internalModel" />
</div>
问题是,现在<div>
(原始<input>
元素)和新<input>
被视为FormController的需要(它处理表单级别的验证) )。当我在链接函数中运行formCtrl.$removeControl(ngModelCtrl)
时,ngModelCtrl尚未附加到表单,但到表单提交时,它已被添加。
此时我唯一能想到的就是将formCtrl.$removeControl(ngModelCtrl)
包裹在$timeout
中,但这似乎不是正确的做法。什么是正确的方法?
我使用的是Angular 1.0.7
答案 0 :(得分:1)
如何让它简单地显示为文本框中的“$”符号? See here:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.currency-input{
padding:.3em;
display:inline-block;
background-color:#fff;
box-shadow:inset 0px 0px 3px #ddd;
border:solid 1px #aaa;
font-size:14px;
}
.currency-input input{
border:0px;
outline:0px;
font-size:14px;
}
<style>
</head>
<body>
<div class='currency-input'>
$<input />
</div>
</body>
</html>
答案 1 :(得分:0)
事实证明,这可以通过将formCtrl.$removeControl(ngModelCtrl)
包装在没有超时值的$timeout
中来实现。所以
if($input.attr('required') === 'required') {
// formCtrl doesn't have ngModelCtrl attached at this point
formCtrl.$removeControl(ngModelCtrl);
}
变为
if($input.attr('required') === 'required') {
// formCtrl doesn't have ngModelCtrl attached at this point
$timeout(function() {
formCtrl.$removeControl(ngModelCtrl);
});
}
我不确定是什么阻止了同步运行,但是现在它会做(在工作中,不能花太多时间在它上面)。