如何在Angular 2中的无效字段上显示“has-error”类

时间:2016-05-08 16:50:15

标签: javascript angular

假设:

<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'标记了它)

3 个答案:

答案 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.htmlhttps://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