我很难实现与AngularJS中的解析器和格式化程序相同的功能。 我的用例不直接是解析器/格式化程序,但这是我要完成的工作。
我有一个动态的键列表。 对于这些键中的每一个,用户都可以输入0-100的值。 如果用户输入(键盘或粘贴)任何字符,它们将被删除。 如果用户输入的数字大于100,则上限为100。
为此,我创建了一个指令来过滤出我需要的内容。
该伪指令可以在input
元素上正常运行,但是基础form
却无法获得正确的值,如下所示。
无论如何,该表格似乎都是我的最后输入。
如何防止更新无效值的模型?
我为此创建了一个StackBlitz。代码的要旨是:
app.component.html
<form #form="ngForm">
<div *ngFor="let key of list">
<input name="{{key}}" ngModel appFilter >
</div>
</form>
<pre>
form:
{{ form.value | json }}
</pre>
app.component.ts
export class AppComponent {
readonly list = ['foo', 'bar'];
}
filter.directive.ts
@Directive({
selector: 'input[appFilter]',
})
export class FilterDirective {
// TODO: remove directive?
@Output()
ngModelChange: EventEmitter<any> = new EventEmitter();
value: string;
@HostListener('input', ['$event'])
onInputChange($event: TextInput) {
const filtered = $event.target.value.replace(/[^0-9]/gi, '');
if (filtered.match(/^[0-9]/)) {
// starts with a number, must be a number
const number = +filtered.replace(/\*/gi, '');
$event.target.value = `${Math.min(100, number)}`;
} else {
// it must be empty string
$event.target.value = '';
}
this.ngModelChange.emit($event.target.value);
}
constructor() {}
}
interface TextInput {
target: {
value: string;
};
}
答案 0 :(得分:1)
通过使用$event.target.value
,您可以调整input
的值,但不能调整基础Angular NgControl
的值。幸运的是,只要具有NgControl
属性的input
也具有关联的appFilter
,ngModel
或formControl
属性,就可以将formControlName
注入到指令中
将NgControl
注入您的FilterDirective
中,并使用它来设置值:
import { NgControl } from '@angular/forms';
constructor(private ngControl: NgControl) { }
@HostListener('input', ['$event'])
onInputChange($event: TextInput) {
const filtered = $event.target.value.replace(/[^0-9]/gi, '');
if (filtered.match(/^[0-9]/)) {
// starts with a number, must be a number
const number = +filtered.replace(/\*/gi, '');
this.ngControl.control.setValue(`${Math.min(100, number)}`);
} else {
// it must be empty string
this.ngControl.control.setValue('');
}
}
您是否应该期望使用FilterDirective
,ngModel
或formControl
属性的formControlName
属性;然后制作注入的NgControl @Optional()
。