Директива для динамического создания шаблона ng

Я пытаюсь создать директиву для элемента input, который будет динамически создавать ng-pattern для проверки действительного IP-адреса в поле ввода. Все мои попытки сделать это были полностью безуспешны. Хотя я могу динамически изменять другие атрибуты, я не могу создать ng-pattern, который повлияет на статус $valid.

Вот код, над которым я работал, кажется, что он должен работать, но он ничего не делает с ng-pattern.

app.directive('ipAddress', function($parse) {
    return {
        link: function(scope, element, attrs) {
            var model = $parse(attrs.ngPattern);
            model.assign(scope, "/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/");
            scope.$apply();
        };
});

Директива:

<input ng-model="ip" ip-address required type="text" id="inputIP" placeholder="xxx.xxx.xxx.xxx">

Да, я знаю, что могу просто указать встроенный ng-pattern с тегом <input>, но дело в том, что я хочу иметь возможность делать это динамически в коде, и я хотел бы, чтобы тег <input> был чище, не встраивая кучу код регулярного выражения там.

Кто-нибудь может мне помочь, пожалуйста! Спасибо!


person Dr. Cool    schedule 29.06.2013    source источник


Ответы (2)


Вы можете определить шаблон в контроллере, а затем использовать в html:

$scope.pat=/^.*$/

А потом в хтмл

<input ng-pattern="pat" ... >
person Piotr Winiarczyk    schedule 03.07.2013
comment
Это действительно хорошо (спасибо!), но я надеялся найти способ установить переменную ngPattern внутри директивы, чтобы HTML-элементу даже не нужно было определять атрибут ng-pattern. - person Dr. Cool; 09.07.2013
comment
Посмотрите здесь: piotrbuda.eu/2013/02/ Хитрость здесь в том, что ctrl.$parsers.push вызывается, когда Angular пытается переместить данные в модель. Вы можете предотвратить это, не возвращая значение. Как и в этом примере, вы также можете установить допустимость ввода. На основе этого примера у меня есть встроенный ввод, который позволяет вводить только числа. То же самое можно сделать и с ИП. - person Piotr Winiarczyk; 10.07.2013
comment
на самом деле предложенное @user2543349 решение не работает. Взгляните на jsfiddle.net/8JzDb/70. Если я заменю ng-pattern=mypattern на ng -pattern=/^\d*$/ работает как положено, принимая только числа. Любые идеи? - person thomdask; 07.08.2013
comment
Не цитируйте шаблоны в коде. Попробуйте точно (без ' ): $scope.mypattern = /^\d*$/; - person Piotr Winiarczyk; 08.08.2013

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

Скорее я бы предложил вам использовать константы, чтобы сделать ваш шаблон глобально доступным, чтобы другие формы могли использовать его также, как директиву, но без накладных расходов.

Вы можете объявить константу следующим образом:

app.constant('FORMATS', { "ipAdressRegex": /^your-regex-here)*$/i });

И используйте эту константу в своем контроллере или сервисе:

var Controller = app.controller('Controller', ['$scope','FORMATS',
function ($scope,FORMATS) {

    $scope.ipAddressPattern = FORMATS.ipAdressRegex;
    .
    .
    .

На ваш взгляд:

<input class="form-control" type="text"
       id="input_ip" name="email" data-ng-model="user.ip_add"
       data-ng-pattern="ipAddressRegex" />

Кроме того, если вы хотите использовать его только в своих представлениях, вы можете вместо этого добавить константу в свой $rootScope вместо создания переменной локальной области видимости в контроллере:

Итак, вместо

$scope.ipAddressPattern = FORMATS.ipAdressRegex;

Вы можете сделать это в своем config.js

_.assign($rootScope, _.pick(FORMATS, 'ipAddressRegex'));

Вид останется прежним

person Snigdha Batra    schedule 22.07.2014