我的目标是创建一个名为“myphone”的Angular指令,只需添加此属性即可在输入字段上执行美国电话号码验证和格式化。我希望验证在键入数据时发生,但我希望在字段失去焦点时进行格式化。提交表单时会发送格式化的电话号码。我花了一些时间想出下面显示的解决方案,我相信它可以按预期工作。
我有几个问题:
(1)我应该在验证器内检查modelValue或viewValue吗?在这种情况下,它们似乎总是相同,所以我想这没关系,但我怀疑一个是“更好”的选择。
(2)从模糊事件更新模型的最佳方法是什么?我想出了scope[ ctrl.$name ] = tel
,但我怀疑这不是一个好方法。好的 - 这不是这样做的方法。显然我应该使用$parse
。
(3)我最初的方法是创建一个格式化程序。看起来格式化程序仅在最初填充字段时调用,而我无法想象如何从blur事件调用格式化程序。这会是一个更好的方法吗?如果是这样,我如何从模糊事件中调用格式化程序?
谢谢!
<!DOCTYPE html>
<html lang="en">
<head><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.min.js"></script></head>
<body>
<form name=form novalidate ng-app="app">
<label>Phone</label>
<input name=phone ng-model="phone" myphone>
<span ng-show="form.phone.$dirty && form.phone.$invalid">Invalid phone.</span>
</form>
<script>
var app = angular.module( 'app', [ ] );
app.directive( 'myphone', [ '$parse', function( $parse )
{
return {
restrict: 'A',
require: 'ngModel',
link: function( scope, elm, attrs, ctrl ) {
ctrl.$validators.myphone = function( modelValue, viewValue ) {
if ( !angular.isString( modelValue ) || !modelValue.length ) return true;
/* Accept a 10 digit phone number. Ignore leading "1" if present. */
var pattern = new RegExp( /^1?[2-9][0-8]\d[2-9]\d{6}$/ );
/* Ignore non-digits */
return pattern.test( viewValue.replace( /[^0-9]/g, '' ) );
};
elm.bind( 'blur', function( ) {
scope.$apply( function ( ) {
var tel = $parse( attrs.ngModel )( scope );
if ( angular.isString ( tel ) ) {
/* Remove non-digits */
tel = tel.replace( /[^0-9]/g, '' );
tel = tel.replace( /^(?:1?)([2-9][0-8]\d)([2-9]\d{2})(\d{4})$/, '($1) $2-$3' );
$parse( attrs.ngModel ).assign( scope, tel );
}
} )
} );
}
};
} ] );
</script>
</html>
答案 0 :(得分:0)
尝试使用angular提供的ng-model-options指令。 详情请见:https://docs.angularjs.org/api/ng/directive/ngModelOptions