Angular filter not working

痴心易碎 提交于 2019-12-23 23:43:39

问题


I am coding a filter that will format phone numbers in a contact form I've built however for some reason the value in the input is never being updated and I'm not sure what I'm doing wrong.

Here's my 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>

and here's my filter:

(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;
            }
        });
})();

I'm not sure if you need this, but here's the controller:

(function () {
    'use strict'

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

If I add an alert(res) before 'return res' in the filter I see the value I expect '123::', however the value in the input it's self is still just 123.


回答1:


You need create directive to change your ngModel, like this:

.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();
             })

         }
     };
 });

Use in html:

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

JS Fiddle: http://jsfiddle.net/57czd36L/1/




回答2:


Though a filter module is a good approach, I personally use a type 'A' directive to do the dirty work. Changing the element value will effect it's ng-model.

However, I would only suggest this kind of solution if your actual data manipulation could be summed in 3-4 lines of code; otherwise a more thorough approach is needed.

This is an example that will delete anything which isn't an integer :

(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\.]/, ''));
                 });
            });
         }
     });
})();

And than in your HTML template :

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



回答3:


Your usage of ngBind on the input is not quite correct. From the documentation,

The ngBind attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes

You do not need to replace the text content of the <input> element, that wouldn't make sense. You can instead extend the formatter pipeline of the NgModelController using a directive like

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

Then, in your HTML,

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

In case you wanted to keep the filter you wrote (for other usages), you can actually re-use it in the directive like

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

$filter('phone') simply returns the filter function registered under 'phone'. Here is a Plunker.


Note, this solution will only format data when you change the $modelValue of the NgModelController, for example like

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

If you are looking for something to update/format the value of the input as the user is typing, this is a more complicated task. I recommend using something like angular-ui/ui-mask.




回答4:


You should remove your "ng-bind" cause you are filtering it and what is presented is what in the ng-model. use value instead.

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

see working example: JsFiddle



来源:https://stackoverflow.com/questions/33246645/angular-filter-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!