简体   繁体   中英

How can I execute action after data-bind in Angular 2?

I'm developing an Angular 2 SPA. My application is composed by:

  • One component
  • One directive

I've builded one directive that format text input using onfocus and onblur events. On focus event remove dots to text value, on blur event add thousand dots to text value.

Following component's code:

<div>
    <input id="input" [(ngModel)]="numero" InputNumber />
</div>

Following component's TypeScript code:

import { Component } from '@angular/core';

@Component({
    selector: 'counter',
    templateUrl: './counter.component.html'
})
export class CounterComponent {
    numero: number;

    public incrementCounter() {
    }

    ngOnInit() {
        this.numero = 100100100;
    }
}

Following directive's TypeScript code:

import { Directive, HostListener, ElementRef, OnInit } from "@angular/core";

@Directive({ selector: "[InputNumber]" })
export class InputNumber implements OnInit, OnChanges {

    private el: HTMLInputElement;

    constructor(private elementRef: ElementRef) {
        this.el = this.elementRef.nativeElement;
    }

    ngOnInit(): void {
       // this.el.value is empty
       console.log("Init " + this.el.value);
       this.el.value = this.numberWithCommas(this.el.value);
    }

    ngOnChanges(changes: any): void {
       // OnChanging value this code is not executed...
       console.log("Change " + this.el.value);
       this.el.value = this.numberWithCommas(this.el.value);
    }

    @HostListener("focus", ["$event.target.value"])
    onFocus(value: string) {
        this.el.value = this.replaceAll(value, ".", "");
    }

    @HostListener("blur", ["$event.target.value"])
    onBlur(value: string) {
        this.el.value = this.numberWithCommas(value);
    }

    private numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
    }

    private escapeRegExp(str) {
        return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
    }

    private replaceAll(str, find, replace) {
        return str.replace(new RegExp(this.escapeRegExp(find), 'g'), replace);
    }
}

The following code works except that I need lost focus for show my number like "100.100.100". How can I perform this action on init data loading?

I add one example at this link: Plnkr example

Thanks

I think that your directive should implement ControlValueAccessor interface https://angular.io/docs/ts/latest/api/forms/index/ControlValueAccessor-interface.html It is needed for writing model in your directive. ControlValueAccessor interface has writeValue(value: any) method that will be initially called. So your writeValue method will be something like this:

private onChange: (_: any) => {};
...
writeValue(val) {
   const editedValue = this.numberWithCommas(val);
   this._onChange(val);
}


registerOnChange(fn: any) : void {
  this._onChange = fn;
}

You can do this by using a Pipe which takes a boolean parameter that represents your focus/no focus action.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'dots'})
export class DotsPipe implements PipeTransform {
  transform(value: number, hasFocus:boolean): any {
    if(hasFocus){
      return value.toString().replace(/\./g,'');
    }else{
      return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
    }
  }
}

Then you have to apply the Pipe on your [ngModel] and use Angular events (focus) and (focusout) to change your variable.

<input [ngModel]="numero | dots : hasFocus" (focus)="hasFocus=true" (focusout)="hasFocus=false" (ngModelChange)="numero=$event" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM