用于转换百分比的自定义指令

问题描述 投票:0回答:3

我正在尝试在 Angular 2 中创建一个自定义指令,它将把输入的值

ngModel
更改为百分比

number / 100

example image

这是我想要实现的目标的示例图像。

例如,用户看到了

5.12
,但是发送到后端的值应该是
5.12 / 100
,但用户看不到这个。

我找到了一种方法,但是,我认为这是一个错误的方法,你们能帮我吗?

这是我的

code

比如从后端来的时候要乘以100,到后端的时候要除以100。

angular angular2-directives
3个回答
4
投票
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

希望对大家有帮助



0
投票

您可以向指令添加

EventEmitter
来输出更改后的值,但您不应更改指令中的
ngModel
值。应添加到组件以保存百分比值的
[ngModel]="employerShare"

这是Plunker

ToPercentage指令:

@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);

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.