Angular 9 中修剪空白的自定义指令

MeV*_*mar 3 angular angular9

我创建了一个自定义指令来从输入框中删除空格,该指令在 Angular 版本 7 之前完全正常工作,但在 Angular 版本 9 中不起作用。

import {
    Directive,
    ElementRef,
    Output,
    EventEmitter,
} from '@angular/core';
@Directive({
    selector: '[trim]',
    host: {
        '(blur)': 'onBlur()'
    }
})
export class TrimDirective {
    @Output() ngModelChange: EventEmitter < any > = new EventEmitter();
    constructor(private element: ElementRef) {}
    onBlur() {
        (this.element.nativeElement as HTMLInputElement).value = (this.element.nativeElement as HTMLInputElement).value.trim();
        this.ngModelChange.emit((this.element.nativeElement as HTMLInputElement).value.trim());
    }
}
Run Code Online (Sandbox Code Playgroud)

在模糊事件中,它应该修剪空白并更新 ngModel,但它不会更新 ngModel

Jul*_*obs 6

以下是我们如何实现它,从 Angular 4.x 到 11.x

正如您将看到的,我们使用选择器,以便将该指令应用于所有输入/文本区域元素,而无需显式使用该指令。

这可以很容易地改变,而是使用“app-trim”

import { Directive, HostListener, forwardRef } from "@angular/core";
import { DefaultValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";

const TRIM_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => TrimValueDirective),
  multi: true
};

/**
 * The trim accessor for writing trimmed value and listening to changes that is
 * used by the {@link NgModel}, {@link FormControlDirective}, and
 * {@link FormControlName} directives.
 */
@Directive({
  selector: `
    input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.app-trim-ignore)[formControlName],
    input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.app-trim-ignore)[formControl],
    input:not([type=checkbox]):not([type=radio]):not([type=password]):not([readonly]):not(.app-trim-ignore)[ngModel],
    textarea:not([readonly]):not(.app-trim-ignore)[formControlName],
    textarea:not([readonly]):not(.app-trim-ignore)[formControl],
    textarea:not([readonly]):not(.app-trim-ignore)[ngModel],
    :not([readonly]):not(.app-trim-ignore)[ngDefaultControl],
    [app-trim]
  `,
  providers: [TRIM_VALUE_ACCESSOR]
})
export class TrimValueDirective extends DefaultValueAccessor {

  @HostListener("input", ["$event.target.value"])
  ngOnChange = (val: string): void => {
    this.onChange(val.trim());
  };

  @HostListener("blur", ["$event.target.value"])
  applyTrim(val: string): void {
    this.writeValue(val.trim());
  }

  writeValue(value: any): void {
    if (typeof value === "string") {
      value = value.trim();
    }

    super.writeValue(value);
  }

}
Run Code Online (Sandbox Code Playgroud)