我正在使用装饰器来标记属性案例类型,当标记为“上”或“下”的属性之一的值发生更改并且新值未正确输入大小写时,我更改大小写,然后将光标移到正确的位置,因为更改 FormControl 的值会将光标放在值的末尾。
无论位置或案例类型如何,这都适用于键入、删除或粘贴文本。
也许可以将其转换为指令,将输入的案例类型传递给该指令,以获得更优雅的解决方案。
以下代码将检查绑定到标记为“上”或“下”的属性的每个 FormControl:
import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';
import { takeUntil, filter } from 'rxjs/operators';
----
constructor(private _renderer2: Renderer2){}
ngOnInit() {
this.getProperties(this.entity)
.filter(prop => new Array<string>('upper', 'lower')
.includes(this.getPropertyCaseType(this.entity, prop)))
.forEach(prop => {
this.form.controls[prop].valueChanges
.pipe(filter(v => {
if (!v) return false;
let caseType = this.getPropertyCaseType(this.entity, prop);
if (caseType === 'upper') return v !== (<string>v).toUpperCase();
if (caseType === 'lower') return v !== (<string>v).toLowerCase();
return false;
}))
.subscribe(t => {
let oldVal = this.form.value[prop];
let currentVal = <string>t;
this.form.controls[prop].setValue(this.getPropertyCaseType(this.entity, prop) === 'upper' ?
currentVal.toUpperCase() :
currentVal.toLowerCase());
let inputElement = this._renderer2.selectRootElement(`#input_${prop}`);
if (!inputElement || !oldVal) return;
let diff: string = '';
for (let i = 0; i < currentVal.length; i++)
if (currentVal[i] !== oldVal[i - diff.length])
diff = `${diff}${currentVal[i]}`;
let diffPosition = currentVal.lastIndexOf(diff);
inputElement.setSelectionRange(diffPosition + diff.length, diffPosition + diff.length);
});
});
}