更改数据时,Angular 2光标会跳到文本框的末尾 [英] Angular 2 Cursor jump at the end of textbox when changing data

查看:174
本文介绍了更改数据时,Angular 2光标会跳到文本框的末尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

名称字段中有一些限制,因此我尝试使用以下指令验证名称字段.内部指令中,我使用正则表达式检查有效名称,然后使用valueAccessor.writeValue(newVal)

There is some restrictions in name field so I am trying to validate name field using directive as below. Inside directive I am using regular expression to check valid name and then replacing valid name into textbox using valueAccessor.writeValue(newVal)

这里的问题是,当我试图在文本框中输入某个单词的中间光标时,光标会跳到最后.

Here issue is when I am trying to type middle of some word in textbox cursor jump at the end.

@Directive({
    selector: '[validateName]',
    host: {
        '(ngModelChange)': 'onInputChange($event, false)',
        '(keydown.backspace)': 'onInputChange($event.target.value, true)',
        '(focusout)': 'removeClass()'
    }
})

export class NameValidator {

    constructor(public model: NgControl,public renderer: Renderer, public el: ElementRef) { }

    onInputChange(event, backspace) {
        if (!backspace) {
            // Remove invalid characters (keep only valid characters)
            var newVal = event.replace(/^[0-9\s]/g, '').replace(/[^A-Za-z0-9_$]/g,'');

            // Add class for invalid name. 
            if (/^[0-9\s]/g.test(event) || /[^A-Za-z0-9_$]/g.test(event)) {
                this.renderer.setElementClass(this.el.nativeElement, 'invalid-name', true);
            }
            else {
                this.renderer.setElementClass(this.el.nativeElement, 'invalid-name', false);
            }
            // set the new value
            this.model.valueAccessor.writeValue(newVal);
        }
    }
    removeClass() {
        this.renderer.setElementClass(this.el.nativeElement, 'invalid-name', false);
    }
}

推荐答案

这是由于DefaultValueAccessor盲目地写入元素值(无论是否存在焦点,是否选择)而产生的.我必须自己处理这种行为,因为我使用的是自动保存的表单,因此我必须重写DefaultValueAccessor并创建一个仅在不同时才写值的表单(我认为这样不行)为您服务,请参见下文):

That comes from the fact DefaultValueAccessor writes blindly the element value, if there is a focus or not, selection or not. I had to do deal with such a behavior myself as I was using a form that was auto-saving and I had to override DefaultValueAccessor and create one that was only writing value if it was different (I don't think that would work for you, see below) :

export const DEFAULT_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DefaultValueAccessor),
    multi: true
};

@Directive({
    selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]",
    host: {"(input)": "onChange($event.target.value)", "(blur)": "onTouched()"},
    providers: [DEFAULT_VALUE_ACCESSOR]
})
export class DefaultValueAccessor implements ControlValueAccessor {
    onChange = (_: any) => {
    };
    onTouched = () => {
    };

    constructor(private _renderer: Renderer, private _elementRef: ElementRef) {
    }

    writeValue(value: any): void {
        const normalizedValue = value == null ? "" : value;
        // line bellow is the only line I added to the original one
        if ((this._elementRef.nativeElement as HTMLInputElement).value !== normalizedValue) 
            this._renderer.setElementProperty(this._elementRef.nativeElement, "value", normalizedValue);
    }

    registerOnChange(fn: (_: any) => void): void {
        this.onChange = fn;
    }

    registerOnTouched(fn: () => void): void {
        this.onTouched = fn;
    }

    setDisabledState(isDisabled: boolean): void {
        this._renderer.setElementProperty(this._elementRef.nativeElement, "disabled", isDisabled);
    }
}

对于您的情况,您可能需要处理输入选择:

For your case, you might need to deal with input selection :

let start=this.el.nativeElement.selectionStart;
let end = this.el.nativeElement.selectionEnd;
this.model.valueAccessor.writeValue(newVal);
this.el.nativeElement.setSelectionRange(start,end);

请注意,由于您正在修改输入内容,因此可能不正确...

Note that it might not be accurate as you are modifying the input...

这篇关于更改数据时,Angular 2光标会跳到文本框的末尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆