2017-04-12 49 views
1

我已經把貨幣屬性指令在ReactiveFormFormControl上輸入事件(的onkeydown)使用@HostListener刪除所有無效字符(字母和符號),因爲它們被輸入到輸入中,但允許數字和小數。 但是,如果您輸入一個無效字符(即a)到一個空的輸入字段並且它被指令刪除,則的型號不是已更新。角使用指令與@HostListener到更新ReactiveForm的輸入值設置輸入到ngValid代替ngInvalid

我已經使用貨幣指令添加了一個plunker設置。要遵循的步驟明白我的問題:

  1. 123a你不要在輸入的a因爲沒有字母是允許的,並且該按鈕被禁用,因爲形式是無效的(好)
  2. 類型123.456你不要在輸入6因爲只有2位小數是允許的,並且該按鈕被禁用,因爲形式是無效的(好)
  3. a你不輸入獲得a ,但是對接啓用,因爲該模型認爲它有一個a在它,即使用戶界面不顯示它(壞)

可以驗證模型不是通過點擊按鈕,並期待在控制檯更新,其日誌this.form.value,並顯示{ amount: 'a' }。如果您接下來輸入有效的字符,模型將只包含該字符,並且a將被刪除。所以只有在這種情況下,模型才能正確更新。

這是使用ngModel validator and parser pipes在AngularJS容易解決的問題,modelValue$setViewValue,並且$render()更新和力AngularJS運行$摘要。你如何在Angular中做到這一點?

這是從我的屬性指令代碼,可成功地修剪掉不需要的字符:

@HostListener('input', ['$event']) 
    onKeyDown(event: KeyboardEvent) { 
    const input = event.target as HTMLInputElement; 

    // Only numbers and decimals 
    let trimmed = input.value.replace(/[^\d\.,]+/g, ''); 

    // Only a single decimal and choose the first one found 
    if (trimmed.split('.').length > 2) { 
     trimmed = trimmed.replace(/\.([^\.]*)$/, '$1'); 
    } 

    // Cannot start with decimal typed or pasted 
    if (trimmed.indexOf('.') === 0) { trimmed = ''; } 

    // AngularJS "like" solution would be something like: 
    // ngModelCtrl.$setViewValue(trimmed); 
    // ngModelCtrl.$render(); 
    // Angular solution is??? 

    input.value = trimmed; 
} 

回答

2

所以我也沒搞清楚,一個解決方案使用NgControl,我注入private ngControl: NgControl下面的代碼,然後訪問它的控制性能this.ngControl.control.patchValue(newValue);,哪些更新在我的onKeyDown事件中的ReactiveForm中輸入字段模型 - 請參閱plunker

但是基於使用智能和啞元組件,使用EventEmitter實際上是一個更好的解決方案,它將輸入值傳遞給父窗體 - plunker(感謝Todd Motto和他的Ultimate Angular課程)

+0

注入NgControl爲我做了竅門,謝謝。 – Hasan

0

隨着近期角4發佈新的指令被引入到處理這些場景

<input [name]="fullName" pattern="[a-zA-Z ]*" [(ngModel)]="..."> 

在您可以指定任何正則表達式的模式

Docs

更新:基於評論,如果您試圖限制用戶輸入字符,則可以使用自定義指令。

使用您的指導作用

@HostListener('keydown') onKeydown() { 
     let value= this.el.nativeElement.value; 
    let key= value.charCodeAt(value.length -1]) 
    let strippedString =''; 
    if(!((key > 64 && key < 91) || (key> 96 && key< 123) || key== 8 || key== 32 || (key>= 48 && key<= 57)){ 
     strippedString = this.el.nativeElement.value.substring(0,value.length-1) 
     this.el.nativeElement.value = strippedString 
    } 

LIVE DEMO

+0

感謝您的回覆。模式驗證程序只會說出什麼地方出現錯誤,但是我會阻止輸入值,而不是警告它不正確。模式自ng1以來實際上已經存在,並且也在ng2中。 – mtpultz

+0

是啊,我在問題中指出我使用的是一個屬性指令,這就是我在問題末尾添加的使用@HostListener的代碼片段的來源。 – mtpultz

+0

正在處理它將更新我的答案等待 – Aravind