【问题标题】:Angular 2 Directive to set input field to uppercase using ngModelChangeAngular 2指令使用ngModelChange将输入字段设置为大写
【发布时间】:2017-11-12 02:48:36
【问题描述】:

请帮忙。我无法创建一个总是将文本输入设置为大写的指令。它似乎正在查看用户界面,但模型绑定显示最后输入的字符仍为小写字符。

以下是我的 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);       
  }
}

【问题讨论】:

    标签: angular2-directives


    【解决方案1】:

    这个问题已经在 SO,here 上得到了回答,尽管解决方案与框架更新版本一起堆积。

    至少根据我的经验,有两个有用的答案,它们本身并不起作用: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 内替换。

    【讨论】:

    • 在 Angular 4.4.1 中(可能在以前的版本中)渲染器已被弃用
    • LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR 的目的是什么?没有它,该指令也能正常工作。
    • @Mouss re。渲染器,非常真实。现在是Renderer2,不知道是从哪个版本开始的。回覆。值访问器(除了在博客文章中解释的那样)我相信它是必需的,以便您的自定义表单参与表单验证/脏/有效/原始/...逻辑编辑是的,请参阅章节在注册herehere
    【解决方案2】:

    您应该使用如下指令,

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

    LIVE DEMO

    【讨论】:

    • 感谢您的回复,但我的问题在于绑定。我修改了你的 plunker 代码以显示:link。当我在文本框上键入时,右侧显示的值仍然是小写值。
    • 你必须在组件中处理它,指令在这种情况下将不起作用,它也是一个文本区域。
    • 我明白了,我会尝试创建一个自定义组件。谢谢!
    • 是的,如果在组件内完成,效果会更好。谢谢!
    • 是的。尽管我仍在寻找是否有一些技巧可以使其与指令一起使用。我已经在整个项目中使用了我原来的方法.. [叹气] PS:我是新来的.. 仍然没有权利给予公众投票。
    猜你喜欢
    • 2018-03-31
    • 2018-07-10
    • 2020-03-31
    • 2014-10-02
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    相关资源
    最近更新 更多