我在文本区域中使用angular(6x)来重新创建一个小的JSON编辑器。
我重新实现了“ CTRL” +“ shift” +“向上/向下箭头”键来上下移动一行,就像在其他桌面文本编辑器中一样。
每次selectionStart和selectionEnd我都必须重新计算,以使选择保持在“相对”位置。 我做到了所有这些,但是我发现“ selectionDirection”已异步替换为“ forward”。
简而言之,我的函数如下所示:
function onKeyDown(event) {
//save starting direction
const direction = event.target.selectionDirection;
//... my magic to find the newString + newSelectionStart + newSelectionEnd. ...
this.jsonString = event.target.value = newString;
event.target.selectionStart = newSelectionStart;
event.target.selectionEnd = newSelectionEnd;
event.target.selectionDirection = direction;
}
和我的模板如下:
<textarea
[value]="jsonString"
(input)="jsonString = $event.target.value"
(keydown)="onKeydown($event)"></textarea>
它可以工作,但是在执行函数后将selectionDirection更改回去。 我知道它被设置为在宏任务中转发(通过setTimeout),因为将其设置为Promise(微任务)不起作用,而将其设置为setTimeout则创建了竞争条件错误。 例如:
//in place of the last line of the function. do nothing.
Promise.resolve().then(() => {event.target.selectionDirection = direction;})
//in place if the last line of the function. do a race condition. it work, but it 'fickle',
//changing from "backward" to "forward" to "backard" each time.
setTimeout(() => {event.target.selectionDirection = direction;});
为什么selectionDirection
改回前进? selectionStart
和selectionEnd
不变,只有selectionDirection
不变。
我唯一能想到的是Angular变化检测机制将jsonarea的值替换为textarea的值,并在此过程中手动保留selectionStart
和selectionEnd
,但selectionDirection
除外。但我对角的内部了解不足以确保这一点。