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

ank*_*boj 17 html5 angular2-forms angular2-template angular

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

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

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

pix*_*its 35

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

<input type="text" #input (input)="input.value=$event.target.value.toUpperCase()" />
Run Code Online (Sandbox Code Playgroud)

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

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

})
export class UpperCaseText {
    constructor(private ref: ElementRef) {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

directives: [UpperCaseText]
Run Code Online (Sandbox Code Playgroud)

演示Plnkr

  • 如果最后一个字符是小写,则在此实现中使用“ input.value = $ event.target.value.toUpperCase()”。angular 4.3 (2认同)

小智 22

这是我的解决方案:

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

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

<input type="text" class="form-control" placeholder="ID"
           formControlName="id" [(ngModel)]="form.value.id" uppercase/>
Run Code Online (Sandbox Code Playgroud)

  • 最后一个小写字符,我该如何解决?(我正在使用角度6) (2认同)

Thi*_*ier 7

我将创建一个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());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

const UPPERCASE_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => UppercaseValueAccessor), multi: true});

@Directive ({
  providers: [ UPPERCASE_VALUE_ACCESSOR ],
  (...)
})
export class UppercaseValueAccessor ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 为了使它与验证(`[class.invalid] ="myControl.touched &&!myControl.valid`)一起工作,响应输入事件我需要调用`super.writeValue(updatedValue); this.onTouched (); this.onChange(updatedValue);` (2认同)

sup*_*jos 7

至少在我的经验中,我发现这里的两个答案很有见地,但不是自己工作:来自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;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是小写的,但一切都适用于大写,只是重命名指令,替换在selectortransformValue.

编辑:
使用此类指令从HTML代码中直接使用示例:

<input id="myField"
       formControlName="myField"
       type="text" class="form-control required" 
       lowercase>
Run Code Online (Sandbox Code Playgroud)


小智 6

<input type="text" oninput="this.value = this.value.toUpperCase()">
works good in angular to get every symbol to be a big one :)
Run Code Online (Sandbox Code Playgroud)


小智 5

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();
    }

    }
Run Code Online (Sandbox Code Playgroud)

这是带有模板的相应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 />
    <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 {}
Run Code Online (Sandbox Code Playgroud)

这是一个展示这一点的Plnkr.