指令未解析初始值

时间:2018-07-25 19:47:27

标签: javascript angular angular6 angular-directive

当前,我正在处理一个指令,该指令必须在用户不关注输入字段时将其显示为货币。直到我从服务器重新加载数据并为输入字段提供起始值之前,这种方法都有效。

每当我初始化输入字段的值时,在用户聚焦并退出输入字段(这是正常行为)之前,解析都不会应用。我正在尝试应用数字的格式,即使用户尚未输入(聚焦)并退出(模糊)字段也是如此。

Representation of the problem

当我加载页面时,左边的字段是输入,当我专注于页面并退出该字段后,右边的字段是输入。即使用户尚未与输入进行交互,我也需要显示正确的表示形式。

我试图在构造函数中和ngInit上应用管道,但是这些点的值仍为'0',所以我认为我不能那样做。我也曾尝试绑定ngOnChanges生命周期和'change'hostListener事件,但均无效。

有什么方法可以使这项工作正常进行吗?还是会成为我页面上的功能?

我的指令:

@Directive({
  selector: '[appCurrencyFormatter]'
})
export class CurrencyFormatterDirective implements OnInit, OnChanges {

    private el: HTMLInputElement;

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

    ngOnInit() {
      // This doesn't work. value at this point is an empty string.
      this.el.value = this.currencyPipe.transform(this.el.value);
    }

    @HostListener('change', ['$event.target.value'])
    ngOnChanges(changes) {
        console.log('change'); // only triggers when user changes the value.
                               // Not when value is set during initialization.
    }

    @HostListener('focus', ['$event.target.value'])
    onFocus(value) {
      this.el.value = this.currencyPipe.parse(value);
    }

    @HostListener('blur', ['$event.target.value'])
    onBlur(value) {
      this.el.value = this.currencyPipe.transform(value);
    }

}

我的html输入:

<input type="text"
       [(ngModel)]="testNumber"
       appCurrencyFormatter />

testNumber刚刚在ngOnInit(){...}中的值22221初始化

目前,我正在使用最新版本的angular6。

2 个答案:

答案 0 :(得分:0)

那是因为指令需要时间来获取模型。您可以尝试执行以下操作:

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

@Directive({
  selector: '[appMyDir]'
})
export class MyDirDirective implements OnInit {

  constructor(private el: ElementRef) { }

  ngOnInit() {
    setTimeout(() => {
      console.log(this.el.nativeElement.value)
    }, 0);
  }

}

答案 1 :(得分:0)

使用ngOnInit生命周期挂钩代替ngAfterViewChecked。这样可以确保该值已经初始化。

export class CurrencyFormatterDirective implements AfterViewChecked {
                                                   ^^^^^^^^^^^^^
 // ...

  ngAfterViewChecked() {
  ^^^^^^^^^^^^^^^
    this.el.value = this.currencyPipe.transform(this.el.value);
  }

看看这个stackblitz

有关AfterViewChecked的更多信息,请查看docs