我正在尝试在 Angular 2 中创建一个自定义指令,它将把输入的值
ngModel
更改为百分比
number / 100
这是我想要实现的目标的示例图像。
例如,用户看到了
5.12
,但是发送到后端的值应该是5.12 / 100
,但用户看不到这个。
我找到了一种方法,但是,我认为这是一个错误的方法,你们能帮我吗?
code
。
比如从后端来的时候要乘以100,到后端的时候要除以100。
import { Directive, ElementRef, Input, forwardRef, EventEmitter } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgModel } from "@angular/forms";
@Directive({
selector: '[ngModel][toPercentage]',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ToPercentDirective),
multi: true
}],
host: {
"[value]": 'ngModel',
'(blur)': 'onBlur()'
}
})
export class ToPercentDirective implements ControlValueAccessor {
constructor(private el: ElementRef) { }
private innerValue: string;
private toNumber: number;
private toPercent: number;
public onChangeCallback: any = (_) => { console.log(_) }
public onTouched: any = () => { /*Empty*/ }
onBlur() {
var input = this.el.nativeElement.value;
this.toPercent = parseFloat(input) / 100;
if (input != this.toNumber) {
this.onChangeCallback(this.toPercent);
}
}
get value(): any {
console.log(this.innerValue);
return this.innerValue;
};
//set accessor including call the onchange callback
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
writeValue(val: string): void {
// this.ngModel.ControlValueAccessor.writeValue(val);
this.toNumber = parseFloat(val) * 100;
this.el.nativeElement.value = this.toNumber;
}
registerOnChange(fn: any): void {
// console.log(fn);
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
// console.log(fn);
this.onTouched = fn;
}
}
我正在为面临类似问题的任何人发布此答案。
它解决了这个问题: 当来自后端时转换数字 * 100 并在发送到后端时转换为数字/100。
但用户看不到这些操作。
例如:
response = 0.5
toNumber = 0.5 * 100 -> <input number> 50
toPercent= 50 / 100 -> <input number> 50, value = 0.5
希望对大家有帮助
您可以向指令添加
EventEmitter
来输出更改后的值,但您不应更改指令中的 ngModel
值。应添加到组件以保存百分比值的 [ngModel]="employerShare"
。
这是Plunker
@Directive({
selector: '[ngModel][toPercentage]',
providers: [NgModel],
})
export class ToPercentageDirective implements OnInit {
@Output() sharedVarChange = new EventEmitter();
constructor(private el: ElementRef,
private ngModel: NgModel) { }
ngOnInit() {
let that = this;
let toPercent:any;
this.ngModel.valueChanges.subscribe(function (value){
toPercent = value / 100;
// that.ngModel.update.emit(toPercent);
that.sharedVarChange.emit(toPercent);
});
// $(that.el.nativeElement.value).bind(function(newVal){
// newVal = toPercent;
// that.ngModel.update.emit(newVal);
// console.log(newVal);
// });
}
// @HostListener("focus", ["$event.target.value"])
// onFocus(value) {
// this.elementRef.nativeElement.value = this.convertPercentage(value);
// }
// onInputChange(event) {
// console.log('Change');
// }
// @HostListener("blur", ["$event.target.value"])
// onBlur(value) {
// this.elementRef.nativeElement.value = this.convertPercentage(value);
// }
convertPercentage(number){
return number / 100;
}
}
@Component({
selector: 'my-app',
template: `
<div>
<h2>Example</h2>
<form>
<input type="number" class="form-control" id="employerShare" required
name="data.insObj.stat['AHV,IV,EO'].employerShare" placeholder="5.125%"
[ngModel]="employerShare"
(ngModelChange)="onChange($event)"
toPercentage
(sharedVarChange)="onSharedVarChange($event)">
</form>
</div>
`,
})
export class App {
employerShare: number;
data = {};
constructor() {
}
onChange ($event){
console.log("onChange: " + $event);
}
onSharedVarChange ($event){
this.data.employerShare = $event;
console.log("onSharedVarChange: " + this.data.employerShare);
}
}