Я использую Angular с Forms версии 4.1.0 и Material version 2.0.0-beta.8. У меня есть поля, которые необходимо пометить как обязательные на основе конфигурации, хранящейся в таблице базы данных, поэтому конкретные поля, которые требуются, могут изменяться в зависимости от этой конфигурации и не известны во время разработки. Я динамически настраиваю Validators.required в моих элементах управления формой на основе этой конфигурации, и все это работает нормально (то есть соответствующие поля становятся красными, если вы оставляете их пустыми после посещения их).
Однако у меня также есть требование пометить все обязательные поля звездочкой после их меток. У меня есть CSS, чтобы сделать это, основываясь на HTML-атрибуте «required», но, к сожалению, Angular не применяет этот атрибут (или любой класс, который я вижу) к полю, просто основываясь на нем, к которому применен Validator.required. Валидатор помещает в него класс ng-invalid, пока он недействителен, но ничего не сохраняется, если он действителен или не тронут.
Есть ли способ, чтобы валидатор автоматически применял атрибут или класс? Может быть, путем расширения Validators.required или иного создания собственного валидатора? В отчаянии я прибегнул к созданию метода isRequired(fieldName)
в моем контроллере и пометил каждое поле [required]="isRequired('fieldName')
на тот случай, если это потребуется в будущей конфигурации, и это работает, но это действительно громоздко и склонно к забыли, так как разработка новых экранов продолжается.
Я довольно новичок в Angular, поэтому раньше никогда не создавал пользовательский валидатор. На самом деле, я подозреваю, что это достаточно распространенное явление, поэтому в CSS-стилизацию Angular вносят некоторые простые изменения. Любое руководство будет с благодарностью!
Отредактировано , чтобы привести пример того, что у меня есть:
<div>
<form [formGroup]="formGroup">
<md-input-container>
<input mdInput type="text" placeholder="name" formControlName="name">
<md-input-container>
<!-- more inputs here -->
</form>
</div>
В моем контроллере:
generateValidators(formGroup: FormGroup) {
// Go get the database configuration for which fields should have
// validators, then apply appropriate validators
Object.keys(this.formGroup.controls).forEach(fieldName) => {
let validators = [];
if(database configuration indicates this field is required) {
validators.push(Validators.required);
}
if(database configuration indicates this field has a max length) {
validators.push(Validators.maxLength(length));
}
// etc.
formGroup.controls[fieldName].setValidators(validators);
}
}
Все это успешно применяет Validators.required к полям, отмеченным как требуемые в базе данных, и они ведут себя так, как ожидается, когда пользователь не может их заполнить. Но это не добавляет HTML-атрибут «required», который как я добавляю звездочку к метке с помощью CSS. Мне нужно как-то пометить поля, к которым прикреплен Validators.required, чтобы я мог использовать CSS для применения звездочки, либо добавив атрибут «required», либо добавив известный класс, который я могу использовать в своем CSS. Примерно так:
.required:after { content:" *"; }
В качестве обходного пути я создал в своем контроллере метод isRequired (string) для поиска конфигурации базы данных по имени поля и обновил свой HTML следующим образом:
<input mdInput type="text" placeholder="name" formControlName="name"
[required]="isRequired('name')">
Работает, но не очень чисто и требует от всех других разработчиков придерживаться этого; тогда как код, который добавляет валидаторы, находится в общем месте, где все компоненты уже видят и используют его. Я также мог бы обновить метод generateValidators (), добавив в него класс или атрибут, в то же время он помещает Validators.required в список валидаторов, если кто-то знает, как это сделать. Я открыт для предложений.