2015-10-20 56 views
2

我正在编写一个过滤器,它将格式化我的联系人窗体中的电话号码但是由于某种原因,输入中的值永远不会更新,我不知道我在做什么错误。角度过滤器不能正常工作

这里是我的HTML:

<div class='form-group'> 
    <input name='phone' ng-model='home.contact.phone' placeholder='(Area code) Phone' required ng-bind='home.contact.phone | phone' /> 
</div> 

,这里是我的过滤器:

(function() { 
    'use strict' 

    angular 
     .module('Allay.phoneFilter', []) 
     .filter('phone', function() { 
      return function (phone) { 
       if(!phone) return ''; 

       var res = phone + '::' // Since this isn't working, I'm doing something super simple, adding a double colon to the end of the phone number. 
       return res; 
      } 
     }); 
})(); 

我不知道,如果你需要这一点,但这里的控制器:

(function() { 
    'use strict' 

    angular 
     .module('Allay', [ 
      'Allay.phoneFilter' 
     ]) 
     .controller('HomeController', function() { 
      var home = this; 
     }); 
})(); 

如果我在过滤器的'return res'之前添加了一个alert(res),我看到了我期望'123 ::'的值,但是它的输入值是self还只是123

+0

我该怎么做?我在文档中没有看到需要$ scope的任何内容。$ apply()和一个过滤器。 – efarley

+0

好吧,由于您刚刚更改了问题的内容以使我的答案无效,因此我会假设其他答案中的一个会有所帮助。 – Claies

回答

1

您需要创建指令来改变你的ngModel,像这样:

<input name='phone' ng-model='contact.phone' placeholder='(Area code) Phone' required phone-format /> 

JS小提琴:在HTML

.directive('phoneFormat', function() { 
    return { 
     require: 'ngModel', 
     link: function(scope, elem, attrs, ctrl) { 

      var setvalue = function() { 
       elem.val(ctrl.$modelValue + "::"); 
      }; 

      ctrl.$parsers.push(function(v) { 
       return v.replace(/::/, ''); 
      }) 


      ctrl.$render = function() { 
       setvalue(); 
      } 

      elem.bind('change', function() { 
       setvalue(); 
      }) 

     } 
    }; 
}); 

使用http://jsfiddle.net/57czd36L/1/

+1

没有必要创建一个指令,他使用过滤器的方法是正确的。 – Cyberdelphos

+2

@Cyber​​delphos这里是你的解决方案http://jsfiddle.net/wuxfurdn/和在控制台中是错误 - 不可分配的模型表达式:contact.phone |电话() –

+0

我认为这个想法是使用指令来修改DOM行为或向控制器添加行为并在转换值时使用过滤器,例如我正在做的。 – efarley

-2

您应该删除你的“ng-bind”是因为你正在过滤它,所呈现的是ng模型中的内容。使用值来代替。

<input name='phone' ng-model='home.contact.phone | phone' value="{{contact.phone | phone}}" /> 

看到工作示例:JsFiddle

+0

他已经改变/纠正了双模块定义在他的问题中...所以只有你的第一点适用于这里... – Cyberdelphos

+0

由于某些原因,你的例子中的输入不能改变。它固定在任何初始值。 – efarley

+0

@efarley - 更新我的小提琴 –

1

虽然过滤器模块是一个好方法,我个人使用一个“A”型指令做肮脏的工作。更改元素值将影响它的ng模型。

但是,我只会建议这种解决方案,如果您的实际数据处理可以在3-4行代码中求和;否则需要更彻底的方法。

这是将删除任何东西是不是整数的例子:

(function() { 
'use strict' 
angular.module('Allay') 
    .directive('phoneValidator', function() { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs) { 
       angular.element(element).on('keyup', function() { 
         element.val(element.val().replace(/[^0-9\.]/, '')); 
       }); 
      }); 
     } 
    }); 
})(); 

,比你的HTML模板:

<input name="phone" ng-model="home.contact.phone" placeholder="(Area code) Phone" phoneValidator required/>` 
1

您输入的ngBind说法并不正确。从文档,

ngBind属性告诉角来代替与给定表达式的值指定的HTML元素的文本内容,并且当该表达式的值改变

更新文本内容

您不需要替换<input>元素的文本内容,这是没有意义的。你可以去继承使用指令的NgModelController的格式化管道像

app.directive('phoneFormat', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModel) { 
      ngModel.$formatters.push(function (value) { 
       if (value) 
        return value + '::'; 
      }); 
     } 
    } 
}); 

然后,在你的HTML,

<input ng-model='home.contact.phone' phone-format /> 

如果你想保持你写的过滤器(用于其他用途),在该指令实际上你可以重新使用它像

app.directive('phoneFormat', [ '$filter', function ($filter) { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModel) { 
      ngModel.$formatters.push($filter('phone')); 
     } 
    } 
}]); 

$filter('phone')只是返回'phone'下注册的过滤功能。这是一个Plunker


注意,该解决方案将只格式的数据当您更改NgModelController$modelValue,例如像

$scope.$apply('home.contact.phone = "123-456-7890"'); 

如果你正在寻找的东西更新/格式化输入的价值当用户输入时,这是一个更复杂的任务。我推荐使用类似angular-ui/ui-mask的东西。

+1

@xRoyDot,同意你的意见,这是一个正确的方向。但是,在用户打字时“屏蔽”输入值是一件非常困难的工作。如果操作不当,对用户来说非常烦人。例如,在编辑输入的中间时,您必须担心保留光标位置。 ui-mask _does_很好地完成任务。 –