Angular 4 & Bootstrap 4 - 整合验证 类

Angular 4 & Bootstrap 4 - Consolidating Validation Classes

我今天发现我的应用程序中并不总是正确显示验证。在一个特定示例中,如果选择 <option [ngValue]="null">,angular 将因 required 而失败;但是,浏览器会看到 <option value="0: null"> 并且不会在 required.

上失败

我想切换到使用 Bootstrap 的服务器端验证 类 以手动控制何时显示验证:https://getbootstrap.com/docs/4.0/components/forms/#server-side

Angular 有 ng-validng-invalid,Bootstrap 有 is-validis-invalid。我不想复制 bootstrap CSS 而只是更改名称。相反,如果有一种方法可以检测 angular 类 并自动添加 bootstrap 等价物,那就太好了,就像这样:

<select #s="ngModel"
        id="s"
        name="s"
        [ngModel]="myModel"
        required
        class="form-control"
        [class.is-valid]="s.valid"
        [class.is-invalid]="s.invalid">
    <option [ngValue]="null">Choose a value</option>
    <option *ngFor="let item of items" [ngValue]="item.id">{{item.Name}}</option>
</select>

如果有一种方法不需要在每个输入上重复那些 [class...] 属性就可以做到这一点,那就太理想了。

我实际上查看了 Angular 源代码以了解它们如何普遍应用 ng-validng-invalidhttps://github.com/angular/angular/blob/4.4.5/packages/forms/src/directives/ng_control_status.ts#L38-L57

我最终采用了他们的代码并创建了我自己的指令,该指令仅发出 bootstrap 验证 类:

import { Directive, Self } from "@angular/core";
import { NgControl } from "@angular/forms";

const controlStatusHost = {
    "[class.is-valid]": "ngClassValid",
    "[class.is-invalid]": "ngClassInvalid"
};

@Directive({ selector: "[formControlName],[ngModel],[formControl]", host: controlStatusHost })
export class BSControlStatusDirective {
    public constructor(@Self() private control: NgControl) {
    }

    get ngClassValid(): boolean {
        if (this.control.control == null) {
            return false;
        }
        return this.control.control.valid;
    }

    get ngClassInvalid(): boolean {
        if (this.control.control == null) {
            return false;
        }
        return this.control.control.invalid;;
    }
}

装饰器上的 host 属性 才是真正发挥所有魔力的地方。非常整洁!