2017-02-10 36 views
9

在AngularJS中有一個名爲ng-messages的表單指令,它幫助我們使它不會同時顯示所有表單錯誤。例如,如果輸入有3個錯誤:required,minlength,maxlength。然後只需要顯示,在需要有效後,最小長度顯示。如果沒有ng消息,我們需要做一些非常複雜和難看的邏輯,以便只顯示必要的而不是其他的邏輯,同時也考慮到只有當表單控件也是髒/被觸摸且無效時纔會顯示錯誤。AngularJS中如何解決相同的問題,即ng-messages在AngularJS中解決?

在AngularJS,這將是這樣的:

<div ng-messages="form.username.$error" ng-if="form.username.$touched || form.username.$dirty"> 
    <div ng-message="required">Please enter a username.</div> 
    <div ng-message="minlength">Username must be at least 3 characters.</div> 
    <div ng-message="maxlength">Username can't exceed 30 characters.</div> 
</div> 

,我們怎樣才能優雅的方式做到這一點的角?

回答

11

您可以製作自己的組件。下面我提供一個例子(沒有編譯或運行它,但它應該給你足夠的信息去實現)。只有在觸摸,骯髒等情況下才顯示消息的邏輯可以輕鬆添加到此處。

使用

<validation-messages [for]="control"> 
    <validation-message name="required">This field is required</validation-message> 
</validation-messages> 

實施

import { Component, OnInit, ContentChildren, QueryList, Input, OnDestroy } from '@angular/core'; 
import { FormControl } from '@angular/forms'; 
import { Subscription } from 'rxjs'; 

@Component({ 
    selector: 'validation-messages', 
    template: '<ng-content></ng-content>' 
}) 
export class ValidationMessagesComponent implements OnInit, OnDestroy { 
    @Input() for: FormControl; 
    @ContentChildren(ValidationMessageComponent) messageComponents: QueryList<ValidationMessageComponent>; 

    private statusChangesSubscription: Subscription; 

    ngOnInit() { 
    this.statusChangesSubscription = this.for.statusChanges.subscribe(x => { 
     this.messageComponents.forEach(messageComponent => messageComponent.show = false); 

     if (this.for.status === 'INVALID') { 
     let firstErrorMessageComponent = this.messageComponents.find(messageComponent => { 
      return messageComponent.showsErrorIncludedIn(Object.keys(this.for.errors)); 
     }); 

     firstErrorMessageComponent.show = true; 
     } 
    }); 
    } 

    ngOnDestroy() { 
    this.statusChangesSubscription.unsubscribe(); 
    } 
} 


@Component({ 
    selector: 'validation-message', 
    template: '<div *ngIf="show"><ng-content></ng-content></div>' 
}) 
export class ValidationMessageComponent { 
    @Input() name: string; 
    show: boolean = false; 

    showsErrorIncludedIn(errors: string[]): boolean { 
    return errors.some(error => error === this.name); 
    } 
} 
+0

什麼是'[供] = 「控制」',其中'control'從何而來? – Felix

+0

'control'是你想要在'ValidationMessagesComponent'中顯示驗證的'FormControl'。當使用[反應形式](https://angular.io/guide/reactive-forms)時,您可以自己創建這些實例。當使用[template-driven forms](https://angular.io/guide/forms)時,Angular本身會生成這些實例。我的解決方案對反應形式最好/最簡單。 –

+0

幹得不錯。稍微調整一下,對我來說完美無缺。 :) –