ng-pattern не работает внутри директивы

Я пытаюсь завернуть <input> в директиве, так что я могу обработать проверку даты и преобразовать ее из строки в фактическую Date возражать и поддерживать Date версия в оригинальном объеме. Это взаимодействие работает, как и ожидалось. Но ng-pattern на <input> элемент не действует правильно. Это никогда не отменяет <input> независимо от того, что вводится.

HTML

<pl-date date="date"></pl-date>

JS

.directive("plDate", function (dateFilter) {
  return {
    restrict: 'E',
    replace: true,
    template: '<input id="birthDateDir" name="birthDate" type="text" ng-pattern="{{getDatePattern()}}" ng-model="dateInput">',
    scope: {
        date: '='
    },
    link: function (scope) {
        scope.dateInput = dateFilter(scope.date, 'MM/dd/yyyy');

        scope.$watch('date', function (newVal) {
            if (newVal !== scope.tmp) {
                if (!newVal) {
                    scope.dateInput = null;
                } else {
                    scope.dateInput = dateFilter(scope.date, 'MM/dd/yyyy');
                }
            }
        });

        scope.getDatePattern = function () {
            var exp = '/';

            // Removed for brevity

            exp += '/';

            return exp;
        };

        scope.$watch('dateInput', function (newVal) {
            if (newVal !== null) {
                scope.date = new Date(newVal);
                scope.tmp = scope.date;
            }
        });
    }
};

JSFiddle здесь: https://jsfiddle.net/e5qu5rgy/1/

Любая помощь с благодарностью!

1 ответ

Похоже, проблему можно решить, изменив link функция для директивы быть controller функция вместо этого, следующим образом

.directive("plDate", function (dateFilter) {
    return {
        restrict: 'E',
        replace: true,
        template: '<input id="birthDateDir" name="birthDate" class="formField" type="text" ng-pattern="{{getDatePattern()}}" ng-model="dateInput">',
        scope: {
            date: '='
        },
        controller: function ($scope, $element, $attrs) {
            $scope.dateInput = dateFilter($scope.date, 'MM/dd/yyyy');

            $scope.$watch('date', function (newVal) {
                if (newVal !== $scope.tmp) {
                    if (!newVal) {
                        $scope.dateInput = null;
                    } else if (newVal.toString() !== "Invalid Date") {
                        $scope.dateInput = dateFilter($scope.date, 'MM/dd/yyyy');
                    }
                }
            });

            $scope.getDatePattern = function() {
                var exp = '/';

                // Months with 31 days
                exp += '^(0?[13578]|1[02])[\/.](0?[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2}$';

                //Months with 30 days
                exp += '|^(0?[469]|11)[\/.](0?[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2}$';

                // February in a normal year
                exp += '|^(0?2)[\/.](0?[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2}$';

                // February in a leap year
                exp += '|^(0?2)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000)$';

                exp += '/';

                return exp;
            };

            $scope.$watch('dateInput', function (newVal) {
                if (newVal !== null) {
                    $scope.date = new Date(newVal);
                    $scope.tmp = $scope.date;
                }
            });
        }
    };
});

Прежде чем идти в производство, controller необходимо изменить, чтобы использовать массив в качестве аргументов для защиты от минимизации.

Другие вопросы по тегам