假设:
<div class="form-group" [fieldValidity]="email">
<label for="email" class="sr-only">Email</label>
<input [(ngModel)]="model.email" ngControl="email" required>
</div>
我的自定义[fieldValidity]指令:
import { Directive, ElementRef, Input } from 'angular2/core';
import {NgControlName} from 'angular2/common';
@Directive({
selector: '[fieldValidity]'
})
export class FieldValidityDirective {
private el: HTMLElement;
@Input('fieldValidity') field: NgControlName;
constructor(el: ElementRef) {
this.el = el.nativeElement;
}
private _onValidityChange(value: string) {
//TODO test field.valid || field.pristine
if (?) {
this.el.classList.remove('has-error');
} else {
this.el.classList.add('has-error');
}
}
}
如何订阅field.valid&amp;&amp;字段.pristine值来显示错误? (我在下面用'TODO'标记了它)
答案 0 :(得分:4)
一种简单的方法是使用数据驱动方法和[ngClass]指令,如下所示
模板:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div class="form-group">
<div [ngClass]="{'has-error': form.controls['description'].invalid}">
<input type="text" formControlName="description" class="form-control" required [(ngModel)]="description">
</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
组件:
export class FormComponent implements OnInit {
private form: FormGroup;
private description: string;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.form = this.formBuilder.group({
description: new FormControl('')
});
}
}
答案 1 :(得分:3)
您还可以实施ngDoCheck
方法来检查有效性:
ngDoCheck(value: string) {
if (field.valid || field.pristine) {
this.el.classList.remove('has-error');
} else {
this.el.classList.add('has-error');
}
}
那就是说你可以实现一个直接在元素上利用ngClass
的包装组件。这样的事情:
@Component({
selector: 'field',
template: `
<div class="form-group form-group-sm" [ngClass]="{'has-error':state && !state.valid}">
<label for="for" class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-8">
<!-- Input, textarea or select -->
<ng-content></ng-content>
<span *ngIf="state && !state.valid" class="help-block text-danger">
<span *ngIf="state.errors.required">The field is required</span>
</span>
</div>
</div>
`
})
export class FormFieldComponent {
@Input()
label: string;
@Input()
state: Control;
}
您甚至可以使用ng-content
装饰器直接引用@ContentChild
中的控件来进一步:
@Component({
(...)
})
export class FormFieldComponent {
@Input()
label: string;
@ContentChild(NgFormControl) state;
(...)
}
这样您就可以使用ngFormControl
以这种方式定义输入(也适用于ngControl
):
<form [ngFormModel]="companyForm">
<field label="Name">
<input [ngFormControl]="companyForm.controls.name"
[(ngModel)]="company.name"/>
</field>
</form>
有关详细信息,请参阅此文章(&#34;字段&#34的表单组件;):
答案 2 :(得分:2)
让您的验证检查https://angular.io/docs/ts/latest/api/common/FormBuilder-class.html或https://angular.io/docs/ts/latest/cookbook/dynamic-form.html中显示的验证器,并在Angular设置ng-invalid
类时使用如下指令设置自定义类,或者只使用{ {1}}类Angular已经设置而不是引入新的。
ng-invalid
您需要将@Directive({
selector: 'input'
})
export class AddClass {
@HostBinding('class.has-error')
hasError:boolean = false;
@Input('class') classes;
ngOnChanges() {
this.hasError = classes.split(' ').indexOf('ng-invalid') >= 0);
}
}
指令添加到要使用它的组件的AddClass
。