Rém*_*AIX 20 css forms twitter-bootstrap-4 angular
我对Angular很新,我正在尝试使用Angular和Bootstrap 4创建一个注册表单.
我想要的结果是使用Bootstrap的样式和Angular的验证.更准确地说,在验证表单时,Angular在两个不同的位置应用样式(ng-valid,ng-invalid等):input元素和表单元素.
两个问题:
1)由于Bootstrap使用'has-danger'和'has-success'而不是'ng- [in] valid',是否可以配置angular来使用这些样式而不是默认样式.目前,我正在考虑通过添加角度样式来扩展引导程序(使用@extend has-danger/success)
2)Angular将样式应用于输入和表单元素,而bootstrap则在form-group元素上使用它.是否可以将角度放在那里而不是输入元素(或两者?)
我正在使用反应形式,我想避免像(未经测试)这样的事情:
<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>
Run Code Online (Sandbox Code Playgroud)
实现这一目标有一种简单的方法(不是太冗长)吗?
Oli*_*ver 25
如果您正在使用SASS,则可以执行以下操作而无需重写所有css.
.ng-touched.ng-invalid {
@extend .is-invalid;
}
Run Code Online (Sandbox Code Playgroud)
注意:您需要导入bootstrap作为SASS构建的一部分,而不是直接引用它.
如果您没有使用SASS,那么安装就可以看到 Angular CLI SASS选项
yan*_*kee 12
另一个选择是这个指令:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
is-invalid
如果字段被触摸或无效,它只是将类添加到每个字段.它基本上与Oliver的SASS解决方案相同,但在没有SASS的情况下也可以使用,并且可能还有较小的编译输出.
在查看 Angular 文档时想到的最好的想法是使用指令。我的实现仅适用于反应式表单,并且您想要应用样式的元素包含表单控件(如果您使用引导程序,就是这种情况)。应扩展以与 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
组件:
@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]
});
}
}
Run Code Online (Sandbox Code Playgroud)
及其模板:
<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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9673 次 |
最近记录: |