Angularjs 从模糊事件更新模型的最佳方法是什么?

Angularjs 从模糊事件更新模型的最佳方法是什么?,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我的目标是创建一个名为“myphone”的Angular指令,它只需添加此属性,即可对输入字段执行US电话号码验证和格式化。我希望在键入数据时进行验证,但希望在字段失去焦点时进行格式化。提交表单时会发送格式化的电话号码。我花了一些时间,想出了如下所示的解决方案,我相信它能按预期工作 不过,我有几个问题: (1) 我应该在验证器中检查modelValue还是viewValue?在这种情况下,它们看起来总是一样的,所以我想这没关系,但我怀疑其中一个是一个“更好”的选择 (2) 从模糊事件更新模型的最

我的目标是创建一个名为“myphone”的Angular指令,它只需添加此属性,即可对输入字段执行US电话号码验证和格式化。我希望在键入数据时进行验证,但希望在字段失去焦点时进行格式化。提交表单时会发送格式化的电话号码。我花了一些时间,想出了如下所示的解决方案,我相信它能按预期工作

不过,我有几个问题:

(1) 我应该在验证器中检查modelValue还是viewValue?在这种情况下,它们看起来总是一样的,所以我想这没关系,但我怀疑其中一个是一个“更好”的选择

(2) 从模糊事件更新模型的最佳方法是什么?我提出了
scope[ctrl.$name]=tel
,但我怀疑这不是一个很好的方法。好吧,那不是这样做的。显然我应该使用
$parse

(3) 我最初的方法是创建格式化程序。似乎只有在最初填充字段时才会调用格式化程序,我不知道如何从blur事件调用格式化程序。这是一个更好的方法吗?如果是,如何从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>

电话
无效电话。
var-app=angular.module('app',[]);
app.directive('myphone',['$parse',function($parse)
{
返回{
限制:“A”,
要求:'ngModel',
链接:函数(范围、elm、属性、ctrl){
ctrl.$validators.myphone=函数(modelValue、viewValue){
如果(!angular.isString(modelValue)| |!modelValue.length)返回true;
/*接受10位数的电话号码。忽略前导“1”(如果存在)*/
var pattern=newregexp(/^1?[2-9][0-8]\d[2-9]\d{6}$/);
/*忽略非数字*/
返回模式.test(viewValue.replace(/[^0-9]/g');
};
elm.bind('blur',function(){
作用域:$apply(函数(){
var tel=$parse(attrs.ngModel)(范围);
if(角形isString(电话)){
/*删除非数字*/
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);
}
} )
} );
}
};
} ] );

试试angular提供的ng型号选项指令。
更多信息请访问:

谢谢。我试了一下。如果我将更新延迟到模糊事件,则验证也会延迟。