Angular filter not working

Refresh

December 2018

Views

427 time

2

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.

4 answers

1

Вам необходимо создать директиву изменить ngModel, как это:

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

         }
     };
 });

Использование в HTML:

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

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

1

Хотя модуль фильтра хороший подход, я лично использую тип «А» директиву, чтобы сделать грязную работу. Изменение значения элемента будет влиять на это нг-модель.

Тем не менее , я хотел бы только предложить такого рода решения , если ваши фактические данные манипуляции можно суммировать в 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/>`
-2

Вы должны удалить «нг-привязку» причину вы ее фильтрации и тем, что представлено в то, что в нг-модели. использовать вместо этого значения.

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

см рабочего примера: JsFiddle

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 .


Обратите внимание, что это решение будет только формат данных , когда вы меняете $modelValueиз NgModelController, например , как

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

Если вы ищете что - то , чтобы обновить / форматировать значение ввода как пользователь печатает , это более сложная задача. Я рекомендую использовать что - то вроде углового Ui / ш-маски .