2016-12-02 10 views
4

меня возникли проблемы с директивой Angular2, что необходимо сделать следующее: «»Angular2 KeyUp обновление событий положение ngModel курсор переходит в конец

  • Detect, если пользователь вводит персонаж.
  • Если следующий символ также «.», Удалите дубликат «.». и переместите позицию курсора в положение «.». char

У меня есть работа выше, однако при использовании этого в сочетании с ngModel позиция курсора прыгает до конца каждый раз, когда модель обновляется.

вход:

<input type="text" name="test" [(ngModel)]="testInput" testDirective/> 

директива:

import {Directive, ElementRef, Renderer, HostListener, Output, EventEmitter} from '@angular/core'; 

@Directive({ 
    selector: '[testDirective][ngModel]' 
}) 
export class TestDirective { 


    @Output() ngModelChange: EventEmitter<any> = new EventEmitter(); 

    constructor(private el: ElementRef, 
    private render: Renderer) { } 

    @HostListener('keyup', ['$event']) onInputChange(event) { 
    // get position 
    let pos = this.el.nativeElement.selectionStart; 

    let val = this.el.nativeElement.value; 

    // if key is '.' and next character is '.', skip position 
    if (event.key === '.' && 
     val.charAt(pos) === '.') { 

     // remove duplicate periods 
     val = val.replace(duplicatePeriods, '.'); 

     this.render.setElementProperty(this.el.nativeElement, 'value', val); 
     this.ngModelChange.emit(val); 
     this.el.nativeElement.selectionStart = pos; 
     this.el.nativeElement.selectionEnd = pos; 

    } 
    } 
} 

Это работает, за исключением позиции курсора подскакивает до конца. Удаление строки:

this.ngModelChange.emit(val); 

устраняет проблему и позицию курсора правильно, однако эта модель не обновляется.

Может кто-нибудь порекомендует это решение? Или, может быть, я неправильно подхожу к проблеме?

Благодаря

ответ

6

Вам нужно обернуть следующие строки в SetTimeout() вызова. Причина в том, что вам нужно предоставить время браузера для отображения нового значения и только затем изменить положение курсора, которое будет сброшено после нового рендеринга. К сожалению, это будет немного мерцать, но я не смог найти другого способа заставить его работать.

setTimeout(() => { 
    this.el.nativeElement.selectionStart = pos; 
    this.el.nativeElement.selectionEnd = pos; 
}); 
+1

Я могу подтвердить, что это работает, и мерцание не очень заметно. Это приемлемое решение. Однако я надеялся найти решение без использования setTimeout. – conor

1

Для моего случая, приемлемое решение без использования SetTimeout было:

  1. Не обновлять модель на KeyUp
  2. обновить модель, а не на focusout

    @HostListener('focusout') focusOut() { 
        this.ngModelChange.emit(this.el.nativeElement.value); 
    } 
    

 Смежные вопросы

  • Нет связанных вопросов^_^