模型值不会在角度2中自动修剪

amo*_*mol 10 typescript angular

我正在使用角度2表单验证,我在文本框中设置了所需的验证,当我在文本框中输入任何内容时,它显示所需的错误消息它是可以的但是当我只输入空格时它不会显示所需的错误消息,这意味着角度2不修剪模型值.

在角度1.x中,它会自动修剪模型值,但在角度2中,我看不到此功能.

smn*_*brv 12

好吧,对github进行了长时间的讨论,结果如下:我们必须实现自己的验证器.

这是我到目前为止使用的:

import { ValidatorFn, AsyncValidatorFn, Validators as V, FormControl } from '@angular/forms';

// the need in this validators is the non-trimming angular standard behavior
// see https://github.com/angular/angular/issues/8503
export class Validators {

  public static required(control: FormControl) {
    if (!control.value || typeof control.value === 'string' && !control.value.trim()) {
      return {
        required: true
      };
    }

    return null;
  }

  public static minLength(length: number): ValidatorFn {
    return (control: FormControl) => {
      if (!control.value || typeof control.value === 'string' && control.value.trim().length < length) {
        return {
          minlength: true
        };
      }

      return null;
    };
  }

  public static maxLength(length: number): ValidatorFn {
    return (control: FormControl) => {
      if (control.value && typeof control.value === 'string' && control.value.trim().length > length) {
        return {
          maxlength: true
        };
      }

      return null;
    };
  }

  public static pattern(pattern: string): ValidatorFn {
    return V.pattern(pattern);
  }

  public static minAmount(amount: number): ValidatorFn {
    return (control: FormControl) => {
      if (control.value && control.value.length < amount) {
        return {
          minamount: true
        };
      }

      return null;
    };
  }

  public static maxAmount(amount: number): ValidatorFn {
    return (control: FormControl) => {
      if (control.value && control.value.length > amount) {
        return {
          maxamount: true
        };
      }

      return null;
    };
  }

  public static compose(validators: ValidatorFn[]): ValidatorFn {
    return V.compose(validators);
  }

  public static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn {
    return V.composeAsync(validators);
  }

};
Run Code Online (Sandbox Code Playgroud)

这模仿的标准maxLength,minLengthrequired为字符串输入但修剪和代理等功能,以通用的标准验证.

要使用它,只需导入验证器而不是@angular/forms一个,例如:

import { FormControl } from '@angular/forms';
import { Validators } from 'path/to/validators';

...
let control = new FormControl('', Validators.compose(
  Validators.required, Validators.minLength(6)
));
...
Run Code Online (Sandbox Code Playgroud)

这可能不会修剪模型,但它解决了请求中指定的验证问题.


Thi*_*ier 6

我认为您需要为此实现自定义值访问器.像这样的东西:

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

@Directive({
  selector: 'input[trim]',
  host: { '(keyup)': 'doOnChange($event.target)' },
  providers: [ TRIM_VALUE_ACCESSOR ]
})
export class TrimValueAccessor extends DefaultValueAccessor {
  onChange = (_) => {};
  onTouched = () => {};

  constructor(private renderer:Renderer) {
  }

  writeValue(value:any):void {
    if (value!=null) {
      super.writeValue(value.toString().trim());
    }
  }

  doOnChange(elt) {
    let val = elt.value.trim();
    this.renderer.setElementProperty(elt, 'value', val);
    this.onChange(val);
  }
}
Run Code Online (Sandbox Code Playgroud)

如果要使用此值访问器,请将相应的指令添加到组件中,并在trim输入中添加属性:

@Component({
  (...)
  template: `
    <input type="text" trim/>
  `,
  directives: [ TrimValueAccessor ]
})
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅此文章("与NgModel兼容的组件"部分):


Val*_*kov 6

另一种解决方案可能是将修剪逻辑放在 FormControl 包装器中。这种方法很简单,不需要第三方依赖,并且可以使用默认验证器,例如requiredminLength

export class TrimFormControl extends FormControl {
    private _value!: string | null;

    get value(): string | null {
        return this._value;
    }

    set value(value: string | null) {
        this._value = value ? value.trim() : value;
    }
}
Run Code Online (Sandbox Code Playgroud)


Kin*_*rio 5

只是我的两分钱:

这两个指令都基于一个简单的事实,即Angular侦听输入事件以实现视图到模型的绑定(不适用于blur或Submit updateOn选项的情况。这些情况也得到处理)。

如果修剪是由输入事件触发的,则第二个也处理插入符的位置。

这些指令使脏状态和接触状态由原始Angular ValueAccessor处理,因此您不会遇到一些奇怪的行为。

ngx-trim-directive演示:https ://angular-86w6nm.stackblitz.io ,编辑者:https ://stackblitz.com/edit/angular-86w6nm