2015-06-15 5 views
1

У меня есть форма, которая может содержать 15-20 полей. Каждый из них содержит атрибут, который выглядит примерно так:Хранение Угловая форма проверки DRY

ng-class='addressForm.city.$invalid && addressForm.city.$touched ? "error" : ""' 

Так у меня есть, что длинная строка кода повторяется 15-20 раз. Это заставляет мои сухие будильники отключиться от большого времени.

Я мог бы разработать свой собственный способ сделать это более сухим, но я не хочу изобретать колесо. Есть ли приемлемый gererally способ держать Угловую форму валидации СУХОЙ?

+0

Разве вы не можете обернуть это каким-то помощником? –

+0

, вы можете проверить недопустимые поля в событии отправки, а затем вы можете изменить это на '' ng-class = '{' error ': addressForm [имя-поля-здесь] .invalid} "' ' – tbutcaru

+0

@DaveNewton Я предполагаю, что это возможность. Открыта для предложений о том, как это может произойти. –

ответ

0

Если это просто стиль, используйте CSS.

Угловой будет добавлять .ng-invalid и .ng-touched для ввода недопустимых и косвенных элементов.

Или вы можете обернуть все это в директиве что-то вроде

angular.module('module').directive('errorClass', function(){ 
    return{ 
     require: 'ngModel', 
     link: function(scope, el, attr, model) { 
      function setClass() { 
       if(model.$touched && model.$invalid) { 
        if(!el.hasClass('error')) { 
         el.addClass('error'); 
        } 
       } else { 
        el.removeClass('error'); 
       } 
      } 

      scope.$watch(function(){ return model.$touched; }, setClass); 
      scope.$watch(function(){ return model.$invalid; }, setClass); 
     } 
    } 
}); 

Также я havn't фактически использовал эту директиву, поэтому может потребоваться некоторые настройки.

+0

Какова ваша область. $ watch смотрит? –

+0

Часы может принимать функцию в качестве первого аргумента вместо строки. В этом случае они наблюдают, была ли затронута или недействительна модель. – Iain

0

Как сказал @lain, вам не нужно добавлять еще один класс (например, error), если поле недействительно, Angular добавляет, что для вас по умолчанию это просто имя, которое отличается (ng-invalid). Вы можете видеть, как это используется here (официальный пример формы из углового).

Если вы все еще хотите сделать это на своем пути, это реализация моего последнего комментария, используя директиву ngChange.

HTML-:

<input type="text" ng-model="addressForm.city" required ng-change="fieldChanged(this, 'city')"> 

Событие изменения:

$scope.fieldChanged = function(el, fieldName){ 
    if($scope.addressForm[fieldName].$invalid && $scope.addressForm[fieldName].$touched) angular.element(el).addClass('error'); 
    else angular.element(el).removeClass('error'); 
} 

Это не хорошая практика (для манипулирования DOM в контроллере), вы должны осуществить это в директиве, но связывание директива для каждого поля добавит наблюдателей, и я лично стараюсь избегать как можно большего использования слишком большого количества наблюдателей.

Более элегантным вариантом было бы объединить это ngChange с ngClass или просто пойти с помощью этой простой манипуляции с DOM в контроллере. Это ваш выбор :)

0

В итоге я создал свою собственную директиву для этого.Я считаю, что следующая директива, когда применяется, будет вести себя эквивалентно следующему:

form(name='addressForm') 
    input(
    type='text' 
    name='city' 
    ng-class='addressForm.city.$invalid && (addressForm.city.$touched || addressForm.$submitted) ? "error" : ""' 
) 

Вместо того, чтобы все, что я могу сделать:

form(name='addressForm') 
    input(
    type='text' 
    name='city' 
    validate-for='addressForm' 
) 

директива будет проверять действительность на:

  • Blur
  • Форма представления
  • Изменение стоимости

Вот код (ES6):

'use strict'; 

class ValidateFor { 
    constructor() { 
    this.restrict = 'A'; 
    this.require = 'ngModel'; 

    this.link = ($scope, $element, $attrs, ngModel) => { 
     var form = $scope[$attrs.validateFor]; 
     var field = form[$element.attr('name')]; 

     $scope.$on('form-submitted',() => { 
     this.checkForErrors(field, $element); 
     }); 

     $scope.$watch(() => ngModel.$modelValue,() => { 
     if (field.$touched) { 
      this.checkForErrors(field, $element); 
     } 
     }); 

     $element.bind('blur',() => { 
     this.checkForErrors(field, $element); 
     }); 
    }; 
    } 

    checkForErrors(field, $element) { 
    if (field.$invalid) { 
     $element.addClass('error'); 
    } else { 
     $element.removeClass('error'); 
    } 
    } 
} 

ValidateFor.$inject = []; 

Вы могли бы даже устранить необходимость подачи имя формы в validate-for. Я просто сделал это, потому что у меня есть ситуации с вложенными формами.

0

valdr выглядит великолепно. Я еще не использовал его, но я попробую его, и он обновит это сообщение позже.

Смежные вопросы