首页 文章

如何将输入值转换为角度2的大写(传递给ngControl的值)

提问于
浏览
12

我试图使用角度为2的ngControl值来验证输入字段 . 我需要验证用户始终以大写形式输入值 .

现在我们需要将用户输入的值转换为大写 . 但是我使用ngControl处理输入字段中的值,而不是ngModel(考虑到我可以使用ngModelChange事件将值更新为大写 . )

那么转换ngControl使用的值的最佳和低成本方法是什么?

8 回答

  • 7

    正如@Eric Martinez建议的那样,您可以创建一个本地模板变量,并将大写字符串绑定到输入事件的value属性:

    <input type="text" #input (input)="input.value=$event.target.value.toUpperCase()" />
    

    或者,您可以将其作为指令:

    @Directive({
        selector: 'input[type=text]',
        host: {
            '(input)': 'ref.nativeElement.value=$event.target.value.toUpperCase()',
        }
    
    })
    export class UpperCaseText {
        constructor(private ref: ElementRef) {
        }
    }
    

    要使用该指令,请在组件的指令列表中指定 UpperCaseText

    directives: [UpperCaseText]
    

    Demo Plnkr

  • 20

    Simple code without directives

    在输入文本的blur事件中,调用一个将值更改为大写的方法,我的名为“cambiaUpper”

    <input id="shortsel" type="text" class="form-control m-b-12" #shortsel="ngModel" name="shortsel" [(ngModel)]="_stockprod.shortName" (blur)="cambiaUpper($event)"/>
    

    在组件(yourComponentFile.ts)中创建接收事件的此方法,从事件中获取值并将其更改为大写 .

    public cambiaUpper(event: any) {
          event.target.value = event.target.value.toUpperCase();
    }
    

    田田!

  • 28

    这是我的解决方案:

    使用主机侦听器侦听输入事件,然后强制它为大写 .

    import {Directive, EventEmitter, HostListener, Output} from '@angular/core';
    @Directive({
      selector: '[ngModel][uppercase]'
    })
    export class UppercaseDirective {
      @Output() ngModelChange: EventEmitter<any> = new EventEmitter();
      value: any;
    
      @HostListener('input', ['$event']) onInputChange($event) {
        this.value = $event.target.value.toUpperCase();
        this.ngModelChange.emit(this.value);
      }
    }
    

    使用此指令,您可以轻松地将输入强制为大写,如下所示:

    <input type="text" class="form-control" placeholder="ID"
               formControlName="id" [(ngModel)]="form.value.id" uppercase/>
    
  • 6

    我将创建一个ControlValueAccessor的自定义实现 . 后者将对应于将监听主机的输入事件的指令 . 这样,您就可以将用户填写的内容大写 . 控件将自动包含大写的值 .

    这是实施:

    @Directive ({
      selector: 'input[uppercase]',
      // When the user updates the input
      host: { '(input)': 'onChange($event.target.value.toUpperCase())' }
    })
    export class UppercaseValueAccessor extends DefaultValueAccessor {
      (...)
    
      // When the code updates the value of the
      // property bound to the input
      writeValue(value:any):void {
        if (value!=null) {
          super.writeValue(value.toUpperCase());
        }
      }
    }
    

    不要忘记在指令提供程序中注册此自定义值访问器 . 这样,您将使用自定义值访问器而不是默认值 .

    const UPPERCASE_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => UppercaseValueAccessor), multi: true});
    
    @Directive ({
      providers: [ UPPERCASE_VALUE_ACCESSOR ],
      (...)
    })
    export class UppercaseValueAccessor ...
    

    并在要使用此方法的组件的directives属性中添加该指令 .

    有关详细信息,请参阅此课程:

    此链接可以提供其他提示(请参阅“与NgModel兼容的组件”部分):

  • 1

    至少根据我的经验,我发现这里的两个答案很有见地,但不是自己工作:from Thierry Templier(还有第一条评论)和from cal .

    我将两者的部分组合在一起,并提出了这个版本,它现在以反应形式使用Angular 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 内替换 .

    Edit:
    使用此类指令的HTML代码中的直接用法示例:

    <input id="myField"
           formControlName="myField"
           type="text" class="form-control required" 
           lowercase>
    
  • 0

    pixelbits提供了一个很好的解决方案,但它在最新版本的Angular(v4.3.1)中不起作用,因为指令是从组件中折旧的 . 我的解决方案仅基于他的答案,但与最新的一起使用

    我提供了一个带有自定义属性指令的通用解决方案,带有一个布尔输入,如果它是真的,它将把输入转换为大写 .

    upper-case.directive.ts:

    import { Directive, ElementRef, Input } from '@angular/core';
         @Directive({
         selector: '[UpperCase]',
         host: {
            '(input)': 'toUpperCase($event.target.value)',
    
         }
    
        })
        export class UpperCaseTextDirective  {
    
        @Input('UpperCase') allowUpperCase: boolean;
        constructor(private ref: ElementRef) {
        }
    
        toUpperCase(value: any) {
            if (this.allowUpperCase)
            this.ref.nativeElement.value = value.toUpperCase();
        }
    
        }
    

    这是带有模板的相应App组件 .

    app.ts

    //our root app component
       import {Component, NgModule, VERSION} from '@angular/core'
       import {BrowserModule} from '@angular/platform-browser'
       import {UpperCaseTextDirective} from './upper-case.directive'
    
        @Component({
        selector: 'my-app',
        template: `
        <div>
          <h2>Hello {{name}}</h2>
          Auto Capitalize True: <input [UpperCase]="true" type="text" #input />
        
    Auto Capitalize False: <input [UpperCase]="allowEdit" type="text"/> </div> `, }) export class App { name:string; allowEdit:boolean; constructor() { this.name = `Angular! v${VERSION.full}`; this.allowEdit= false; } } @NgModule({ imports: [ BrowserModule ], declarations: [ App,UpperCaseTextDirective ], bootstrap: [ App ] }) export class AppModule {}

    这是一个Plnkr,它证明了这一点 .

  • 1

    这是我更通用的解决方案,基本上类似于DefaultValueAccessor,添加了文本“变换器”功能 . 所以你会用

    <input mdInput [transformer]="uppercase" ...>
    

    在你的组件中你有大写的功能(你可以做大写旁边的其他事情,比如实现一个掩码)...

    uppercase(value: string) {
        return value.toUpperCase();
      }
    

    指示...

    import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
    import { Directive, forwardRef, Input, OnChanges, SimpleChanges, Renderer, ElementRef } from '@angular/core';
    import { TextMaskModule, MaskedInputDirective } from 'angular2-text-mask';
    
    @Directive({
      selector: 'input[transformer]',
      // When the user updates the input
      host: { '(input)': 'handleInput($event.target.value)', '(blur)': 'onTouched()' },
      providers: [
        { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextTransformerDirective), multi: true },
      ]
    
    })
    export class TextTransformerDirective implements ControlValueAccessor {
      private inputElement: HTMLInputElement
      lastValue = "";
      onTouched = () => { }
      onChange = (_: any) => { }
      @Input('transformer')
      transformer = (v: string) => v;
    
      constructor(private renderer: Renderer, private element: ElementRef) {
    
      }
    
      handleInput(value: any) {
        let newVal = this.transformer(value);
        if (newVal != value || this.lastValue != newVal) {
          this.lastValue = newVal;
          this.renderer.setElementProperty(this.element.nativeElement, 'value', newVal);
          this.onChange(newVal);
        }
      }
    
      writeValue(value: any) {
        let normalizedValue = value == null ? '' : value;
        normalizedValue = this.transformer(normalizedValue);
        this.renderer.setElementProperty(this.element.nativeElement, 'value', normalizedValue);
      }
    
      registerOnChange(fn: (value: any) => any): void { this.onChange = fn }
    
      registerOnTouched(fn: () => any): void { this.onTouched = fn }
    
    }
    
  • 5

    这是我正在使用angular4的工作代码

    这是你的大写指令

    import { Directive, ElementRef, HostListener } from '@angular/core';
    
    @Directive({
      selector: '[appUpper]'
    })
    export class UpperDirective {
    
      constructor(public ref: ElementRef) { }
    
      @HostListener('input', ['$event']) onInput(event) {
        this.ref.nativeElement.value = event.target.value.toUpperCase();
      }
    
    }
    

    这是您使用大写指令的html文件代码

    <input type="text" id="id" placeholder="id" tabindex="0" formControlName="id" appUpper>
    

相关问题