29

我正在尝试使用 ngControl 在角度 2 中的值来验证输入字段。我需要验证用户是否始终以大写字母输入值。

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

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

4

10 回答 10

38

正如@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]

演示计划

于 2016-03-06T16:43:49.873 回答
24

这是我的解决方案:

使用主机侦听器侦听输入事件,然后将其强制为大写。

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/>
于 2017-06-28T11:45:26.570 回答
10
<input type="text" oninput="this.value = this.value.toUpperCase()">
works good in angular to get every symbol to be a big one :)
于 2019-09-05T20:26:49.907 回答
8

至少根据我的经验,我在这里找到了两个很有见地的答案,但不是靠他们自己起作用:来自 Thierry Templier(也有第一条评论)和来自 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;
  }
}

这适用于小写,但一切也适用于大写,只需重命名指令,在selector和内替换transformValue

编辑:
使用此类指令的 HTML 代码的简单用法示例:

<input id="myField"
       formControlName="myField"
       type="text" class="form-control required" 
       lowercase>
于 2017-08-02T00:10:23.093 回答
8

我将创建 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 ...

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

有关更多详细信息,请参见本课程:

这个链接可以提供额外的提示(参见“NgModel-compatible component”部分):

于 2016-03-06T13:28:50.807 回答
5

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

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

大写.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 组件。

应用程序.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 />
    <br/>
     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

于 2017-07-24T08:51:39.770 回答
2

如果blur您的input文本将值更改为大写

<input type="text" id="firstName" name="firstName" (blur)="$event.target.value = $event.target.value.toUpperCase()">
于 2020-04-08T21:23:16.097 回答
1

没有指令的简单代码

在输入文本的模糊事件中,调用一个将值更改为大写的方法,我的称为“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();
}

多田!

于 2019-02-16T22:55:43.390 回答
1

这是我更通用的解决方案,基本上就像 Def​​aultValueAccessor 添加了文本“转换器”功能。所以你会使用

<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 }

}
于 2017-03-10T22:02:32.963 回答
0

这是我正在使用 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>
于 2018-07-25T07:51:41.573 回答