2016-12-02 108 views
4

我有一個Angular2指令的問題,應該做到以下幾點:Angular2 keyup事件更新ngModel光標位置跳到結束

  • 如果用戶輸入檢測「」字符。
  • 如果下一個字符也是'。',請刪除重複的'。'。並將光標位置移動到'。'之後。 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. 更新模型上,而不是事件的內容

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