Персональный блог Игоря Антонова aka "spider_net"

Асинхронные валидаторы в Angular.JS 1.3


Рубрика: Программирование -> Angular.JS -> JavaScript
Метки: | | |
Просмотров: 2847
Асинхронные валидаторы в Angular.JS 1.3

В середине октября состоялся финальный релиз моего любимого клиентского JS-фреймворка angular.js. Проект дорос до версии 1.3 и помимо типичного набора багфиксов, разработчики добавили в проект абсолютно новый функционал. Одной из наиболее интересных фишек стала поддержка асинхронных валидаторов (async validators).

В предыдущих версиях angular.js, валидаторы были далеки от идеала. Например, банально отсутствовала концепция добавления валидатора для поля, хотя у форм имеется состояние валидности. Добавим к этому геморрой с валидаторами, требующих время на выполнение и получим настоящий ад.

Давайте рассмотрим асинхронные валидаторы в angular.js на примере решения типичной задачи – проверки доступности имени пользователя на этапе заполнения регистрационной формы. Код регистрационной формы ниже:

<form name="myForm" ng-submit="submit()">
    <label>
        Username:
        <input type="text" ng-model="signup.username" required username-validator>
    </label>
    <label>
        Password:
        <input type="password" ng-model="signup.password" required>
    </label>
    <button type="submit" ng-disabled="myForm.$invalid">Sign Up</button>
</form>

Сразу обращаю ваше внимание на валидатор username-validator. Это кастомная директива, выполняющая запрос к back-end’у с целью проверки существования имени пользователя. Ее код приведен ниже:

angular.module('myModule').directive('usernameValidator', function($http, $q) {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            ngModel.$asyncValidators.username = function(modelValue, viewValue) {
                return $http.post('/username-check', {username: viewValue}).then(
                    function(response) {
                        if (!response.data.validUsername) {
                            return $q.reject(response.data.errorMessage);
                        }
                        return true;
                    }
                );
            };
        }
    };
});

Логика валидатора предельно проста: выполняется HTTP запрос и на основании ответа принимается решение о валидности поля. Дальше используется механизм промисов (обещаний): валидатор возвращает обещание и поле будет находится в состоянии проверки, пока оно не исполнится. В случае ошибки, валидируемое поле будет отмечено соответствующим образом.

В рассмотренном выше примере есть один нюанс. Кнопка для отправки остается активной во время ожидания проверки данных валидатором. Кнопка меняет состояние лишь, когда проверка формы завершилась неудачей (myForm.$invalid). Решить описанную выше проблему можно так:

<button type="submit" ng-disabled="myForm.$invalid || myForm.$pending">Sign Up</button>

Посмотреть пример в действии можно здесь.

Автор: Aviv Ben-Yosef

Ссылка на оригинальную заметку: http://www.codelord.net/2014/11/02/angularjs-1-dot-3-taste-async-validators/

Оставьте комментарий!
comments powered by HyperComments