Угловая форма проверки и стили бутстрапа
Я совершенно новый с Angular, и я пытаюсь создать регистрационную форму, используя Angular и Bootstrap 4.
В результате я хотел бы использовать стили Bootstrap с валидацией Angular. Точнее, при проверке формы Angular применяет стили (ng- допустимо, ng- недействительно и т.д.) В двух разных местах: элемент ввода и элемент формы.
Два вопроса:
1) Поскольку Bootstrap использует "has-danger" и "has-success" вместо "ng- [in] valid", можно настроить угловое использование этих стилей вместо стандартного. В настоящее время я рассматриваю возможность расширения бутстрапа путем добавления угловых стилей (с @extend имеет-опасность/успех)
2) Угловая применяет стиль к элементам ввода и формы, тогда как bootstrap ожидает его на элементе группы форм. Возможно ли иметь угловой стиль вместо этого вместо элемента ввода (или обоих?)
Я использую реактивные формы, и я бы хотел избежать таких вещей, как (не тестировалось):
<form>
<div class="form-group" [class.has-error]="!fg.get('username').valid" [class.has-success]="fg.get('username').valid">
<label>Username</label>
<input formControlName="username" type="text"/>
</div>
</form>
Есть ли простой способ (не слишком многословный) достижения этого?
Ответы
Ответ 1
Если вы используете SASS, вы можете сделать следующее, не переписывая все css.
.ng-touched.ng-invalid {
@extend .is-invalid;
}
Примечание. Вам нужно будет импортировать bootstrap как часть вашей сборки SASS вместо ссылки непосредственно.
Если вы не используете SASS, это довольно удобно для установки, см. Здесь Параметры Angular CLI SASS
Ответ 2
Другим вариантом является эта директива:
import {Directive, HostBinding, Self} from '@angular/core';
import {NgControl} from '@angular/forms';
@Directive({
selector: '[formControlName],[ngModel],[formControl]',
})
export class BootstrapValidationCssDirective {
constructor(@Self() private cd: NgControl) {}
@HostBinding('class.is-invalid')
get isInvalid(): boolean {
const control = this.cd.control;
return control ? control.invalid && control.touched : false;
}
}
Он просто добавляет is-invalid
класс для каждого поля, если поле коснулось или недействительно. Он в основном ведет себя так же, как решение Oliver SASS, но обойдется без SASS и может также иметь меньший скомпилированный результат.
Ответ 3
Лучшая идея, которая пришла ко мне, глядя на угловые документы, - это использовать директиву. Моя реализация работает только с реактивными формами, и если элемент, который вы хотите применить к стилю, содержит элемент управления формой (который, если вы используете бутстрап, в этом случае). Должен быть расширен для совместимости с select и textarea.
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'
@Directive({ selector: '[formValidationStyle]' })
export class FormValidationStyleDirective implements OnInit {
@Input('formValidationStyle') private formGroup: FormGroup;
private component: FormControl;
static VALID_STYLE: string = 'has-success';
static INVALID_STYLE: string = 'has-danger';
constructor(private el: ElementRef) { }
ngOnInit(): void {
let componentName: string;
let inputElement = this.el.nativeElement.querySelector('input');
if (inputElement) {
componentName = inputElement.getAttribute('formControlName');
}
if (!componentName) {
console.error('FormValidationStyleDirective: Unable to get the control name. Is the formControlName attribute set correctly?')
return;
}
let control = this.formGroup.get(componentName)
if (!(control instanceof FormControl)) {
console.error('FormValidationStyleDirective: Unable to get the FormControl from the form and the control name: ${componentName}.')
return;
}
this.component = control as FormControl;
this.component.statusChanges.subscribe((status) => {
this.onStatusChange(status);
});
this.onStatusChange(this.component.status);
}
onStatusChange(status: string): void {
let cl = this.el.nativeElement.classList;
if (status == 'VALID') {
cl.add(FormValidationStyleDirective.VALID_STYLE)
cl.remove(FormValidationStyleDirective.INVALID_STYLE)
} else if (status == 'INVALID') {
cl.add(FormValidationStyleDirective.INVALID_STYLE)
cl.remove(FormValidationStyleDirective.VALID_STYLE)
}
}
}
Пример:
Компонент:
@Component({
selector: 'security-register',
templateUrl: './register.component.html'
})
export class RegisterComponent {
registerForm: FormGroup;
constructor(private http: Http, private fb: FormBuilder) {
this.registerForm = this.fb.group({
username: ['', Validators.required]
});
}
}
И его шаблон:
<form [formGroup]="registerForm" novalidate>
<div class="form-group" [formValidationStyle]="registerForm">
<label class="form-control-label" for="dbz-register-username">Login</label>
<input formControlName="username" type="text" class="form-control" id="dbz-register-username" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</form>