2017-06-10 65 views
4

請幫忙。我無法創建一個總是將文本輸入設置爲大寫的指令。它似乎在查看用戶界面,但模型綁定顯示最後輸入的字符仍然以小寫字符顯示。Angular 2指令使用ngModelChange將輸入字段設置爲大寫

下面

是我的HTML的一部分:

<div> 
    <md-input-container fxFlex> 
     <textarea #listCode mdInput [(ngModel)]="listInfo.code" placeholder="List Code" 
        uppercase-code maxlength="50" rows="3" 
        required></textarea> 
     <md-hint align="end">{{listCode.value.length}}/50</md-hint> 
    </md-input-container> 
    {{listInfo.code}} 
</div> 
下面

是指令:

import { Directive } from '@angular/core'; 
import { NgControl } from '@angular/forms'; 

@Directive({ 
    selector: '[ngModel][uppercase-code]', 
    host: { 
    '(ngModelChange)': 'ngOnChanges($event)' 
    } 
}) 
export class UppercaseCodeDirective { 
    constructor(public model: NgControl) {} 
    ngOnChanges(event) { 
    var newVal = event.replace(/[^A-Za-z0-9_]*/g, ''); 
    newVal = newVal.toUpperCase(); 
    this.model.valueAccessor.writeValue(newVal);  
    } 
} 

回答

4

您應該使用如下指令,

@HostListener('keyup') onKeyUp() { 
     this.el.nativeElement.value = this.el.nativeElement.value.toUpperCase(); 

    } 

LIVE DEMO

+0

謝謝你的回覆,但我的問題是與綁定。我修改了你的plunker代碼來顯示:[link](http://plnkr.co/edit/kKzD7TL0I7z391XwhIlO?p=preview)。當我在文本框中輸入時,右側顯示的值仍然具有小寫值。 –

+0

你必須在組件中處理它,並且指令在這種情況下不起作用,它也是一個文本區域。 – Aravind

+0

我明白了,我會嘗試創建一個自定義組件。謝謝! –

1

這個問題已經以某種方式在SO,here上得到解答,儘管解決方案與框架更新的版本一起堆砌起來。

至少在我的經驗中,有兩個有用的答案,無論如何,它們本身並不起作用:from Thierry Templier(還有第一條評論)和from cal

我放在一起的兩個部分,並用這個版本,這是在一個反應​​形式與角4.1.1現在的工作上來:

import { Directive, Renderer, ElementRef, forwardRef } from '@angular/core'; 
import { NG_VALUE_ACCESSOR, DefaultValueAccessor } from '@angular/forms'; 

const LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR = { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => LowerCaseInputDirective), 
    multi: true, 
}; 

@Directive({ 
    selector: 'input[lowercase]', 
    host: { 
    // When the user updates the input 
    '(input)': 'onInput($event.target.value)', 
    '(blur)': 'onTouched()', 
    }, 
    providers: [ 
    LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR, 
    ], 
}) 
export class LowerCaseInputDirective extends DefaultValueAccessor { 

    constructor(renderer: Renderer, elementRef: ElementRef) { 
    super(renderer, elementRef, false); 
    } 

    writeValue(value: any): void { 
    const transformed = this.transformValue(value); 

    super.writeValue(transformed); 
    } 

    onInput(value: any): void { 
    const transformed = this.transformValue(value); 

    super.writeValue(transformed); 
    this.onChange(transformed); 
    } 

    private transformValue(value: any): any { 
    const result = value && typeof value === 'string' 
     ? value.toLowerCase() 
     : value; 

    return result; 
    } 
} 

這是小寫,但一切都適用於大寫,只是重命名指令,在selectortransformValue之間替換。

+1

在角度4.4.1(也許在以前的版本)渲染器已被棄用 – Mouss

+0

LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR的目的是什麼?沒有它,指令工作正常。 – Mouss

+0

@Mouss re。渲染器,非常真實。現在是Renderer2,不知道從哪個版本開始。回覆。價值訪問者(除了像在博客文章中解釋)我相信這是需要的,以便您的自定義窗體參與形成驗證/髒/有效/原始/ ...邏輯**編輯**是的,見章節*註冊* [這裏](https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html)或[這裏](https://medium.com/ @ tarik.nzl /角-2-定製表單控制與驗證-JSON-輸入2b4cf9bc2d73) – superjos