自定义指令转换百分比

时间:2017-04-10 08:12:30

标签: angular angular2-directives

大家好我想尝试在角度2中创建一个自定义指令,它会将输入ngModel的值更改为百分比,例如

数字/ 100

example image

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

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

我已经采取了一种方法,但我认为这是一种错误的做法,你们可以帮助我。

这是我的code

例如:

当它来自后端乘以* 100并且当它转到后端除以/ 100

3 个答案:

答案 0 :(得分: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

希望它可以帮助任何人

答案 1 :(得分:0)

答案 2 :(得分:0)

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

这是Plunker

ToPercentageDirective:

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

  }
}